🎈 변수
변수를 만들 때 자료형을 명시하지 않는 경우가 있기 때문에 var나 val을 사용하여 변수라는 것을 표시해주어야 한다.
만약 자료형을 명시하지 않는 경우엔 그 문자열에 맞는 변수상자가 내부적으로 만들어진다. 일명 '자료형 추론'이라고 한다.
예)
var changeYes
val CHANGE_YES
자료형을 명시하지 않고 변수를 선언하는 것은 괜찮지만, 초기값을 설정하지 않는 경우는 에러가 난다!
예)
// 가능
var name:String = ""
var name = ""
var name:String
// 불가능
var name
만약 처음에 넣어둘 값을 잘 모르겠다면, lateinit키워드를 추가하면 된다.
lateinit
- var 속성에만 사용 가능
- null허용 자료형에 사용불가
- 기본 자료형에 해당하는 속성에 사용불가
- int, boolean, float, double 등
- 생성자에 사용불가
- 사용자 정의 Getter/Setter 속성에 사용불가
예)
class User {
lateinit var age: Int
lateinit var name: String
constructor(age: Int, name: String) {
this.age = age
this.name = name
}
}
🎈 변수의 종류
var
변수상자에 값을 넣거나 빼는 것이 모두 가능
코딩컨벤션 : var을 선언할 때는 소문자로 선언 및 카멜케이스를 적용한다.
val
변수 상자에 한 번 값을 넣으면 빼는 것만 가능. 즉, 값을 바꿀 수 없는 읽기 전용 변수
값을 쉽게 바꿀 수 없다보니 상수와 비슷함. 하지만 언제 어디서든 접근가능한 것은 아님.
(실제 앱을 만들다보면 val을 사용하는 경우가 더 많다.)
코딩컨벤션 : val을 선언할 때는 대문자로 선언 및 스네이크 스타일을 적용한다.
🎈 읽기전용이며 언제 어디서든지 접근이 가능한, 상수
를 만드는 방법
- companion object 사용
- 패키지 변수 사용
예) companion object사용
- const val 키워드를 사용하면 상수를 선언할 수 있음.
- BONUS라는 이름의 상수를 생성.
- companion object키워드로 만든 객체는
동반 객체
라고도 부름. - 동반객체 안에 정의한 변수나 함수는 클래스의 이름으로 직접 접근할 수 있음.
(ex. MainActivity.BONUS)
class MainActivity : AppCompatActivity() {
var first:Int = 0
var second:Int = 0
companion object {
const val BONUS = 100
}
override fun onCreate(savedInstanceState: Bundle?) {
예) 패키지 변수 사용
* constants란 이름의 패키지를 생성
* 해당 폴더에 새 Kotlin class파일을 생성
* 해당 파일에 아무런 클래스 없이 아래와 같은 코드를 집어넣으면, 해당 변수는 패키지 이름과 변수 이름만으로 접근할 수 있는 상수가 됨.
constants 파일의 소스코드
package org.techtown.basic4.constants
var bonus:Int = 100
MainActibity.kt 파일의 소스코드
중략...
import org.techtown.basic4.constants.bonus
class MainActivity : AppCompatActivity() {
중략...
override fun onCreate(savedInstanceState: Bundle?) {
addButton.setOnClickListener {
중략...
val result = first + second + bonus
outputTextView.append("더하기의 결과는 : ${result}")
}
}
}
🎈 자료형
Kotlin은 '타입 기반의 언어'기 때문에 변수를 만들 때 아래와 같이 자료형을 함께 명시해준다.
var count:Int = 0
🎈 Null허용 자료형
우선, Null이란 다음과 같다.
Java에서는 변수값이 null인지 확인하는 과정을 거치며 이 때 null이면 프로그램에 오류가 발생하도록 되어있다.
Kotlin에서는 이러한 문제를 줄이기 위해 변수에 null을 직접 할당하지 못하게 하고 null허용 자료형으로된 변수를 따로 만들어 null을 할당할 수 있도록 한다. 이렇게 되면 값이 null인 경우에도 에러를 발생시키지 않도록 만들 수 있다.
예) 자료형에 null을 허용시킨 것은 래핑(Wrapping)이라 한다.
var name:String?
예) 이를 다시 되돌리는 과정을 언래핑(Unwrapping)이라 한다.
name!!
실습코드
val NUMBER1: Int? = null
//val NUMBER2: Int = null -> 에러발생.
var number1: Int? = 2+5
var number2: Int? = 10
//var number3: Int? = number1 + number2 -> 에러발생. number1과 number2는 null이 될 수도 있다고 설정되어있기 때문.
var number3: Int? = number1!! + number2!! // -> 에러발생X.
// ?를 통해 null혹은 숫자가 될 수 있다고 내가 설정해뒀긴한데, 나 믿고 숫자라고 생각해 라는 의미의 !!를 추가해주었기 때문.
println(number3)
// 다만 주의할 점은, 사실 null일 경우엔 NullPointerException이 발생할 수 있다.
// 결론!!
// 100% 확신하는 경우가 아니면 !!는 사용하지 말자.
🎈 Null Safety
//?
val number: Int = 10 // non-nullable Int
val number: Int? = null // nullable Int
//!! -> 정말 필요한 경우에만 사용하기
val nullableNumberList: List<Int?> = listOf<Int?>(1, 2, 3, 4, 5)
var result: Int = 0
nullableNumberList.forEach {
result += it!!
}
// ?.
val text: String? = "txt"
//val text: String? = null
println(text?.length)
// !!.
//println(text!!.length) -> NullPointerException이 발생해야함
// as?
open class Warrior(var name: String, var power: Int, var type: String){
fun attack(){
println("공격")}
}
class DefenceWarrior (var name: String, var power: Int){ // 상속안함
fun defence(){
println("방어")
}
}
val defenceWarrior = DefenceWarrior("가", 123)
val warrior = defenceWarrior as? Warrior
//val warrior = defenceWarrior as Warrior -> 에러 발생
//println(warrior)
// ?: 엘비스 연산
val text2 : String? = "123"
val nullText: String? = null
var len1: Int = if(text2 != null) text2.length else 0
var len2: Int = text2?.length ?: 0
🎈 Any자료형
어떠한 값이라도 넣을 수 있는 자료형. 충분한 메모리 공간을 가지고 있음.
is 연산자
Any자료형에 어떤 자료형인지 확인할 수 있는 연산자.
예)
val input1:Any = "10"
if (input1 is String) {
val output:String = input1 as String
outputTextView.append("input1은 문자열")
}
as?
위의 예시에서, input1의 값이 숫자로 변환될 수 있는 "10"이 아닌 "가"와 같은 값이라면 예외가 발생할 것임.
예외상황을 만들지 않으려면 변환이 불가능할 경우 null을 반환해줄 수 있도록 as?를 사용하자.
예)
val input1:Any = "10"
if (input1 is String) {
val output:String = input1 as? String
outputTextView.append("input1은 문자열")
}
형변환
문자열 -> 숫자
class MainActivity : AppCompatActivity() {
var first:Int = 0
var second:Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
addButton.setOnClickListener {
val firstStr = firstInput.text.toString()
val secondStr = secondInput.text.toString()
first = firstStr.toInt()
second = secondStr.toInt()
val result = first + second
outputTextView.setText("더하기 결과 : ${result}")
상속한 클래스 간의 캐스팅
open class Warrior(var name: String, var age: Int) {
open fun attack(){ // 오버라이드 해주기 위해 open시키자
println("공격")
}
}
class DefenceWarrior(name: String, age: Int, height: Int): Warrior(name, age){
fun defence() {
println("방어")
}
}
val warrior: Warrior = DefenceWarrior("박소현", 29, 349) // var는 변경이될 수 있기 때문에 스마트 캐스팅이 안된다.
println(warrior.attack()) // warrior.defence()는 사용 불가능. defence기능을 포기하고 warrior타입이 되었기 때문에.
// is -> 타입 체크. true or false가 리턴된다. 그리고 스마트캐스팅 해줌.
if(warrior is DefenceWarrior){
// 스마트 캐스팅
// -> 내가 만든 warrior를 if블럭 안에서는 defenceWarrior로 사용하게 해준다
warrior.defence()
}
// as -> 지정한 타입으로 캐스팅을 시도하고 불가능한 경우에는 예외발생
val warrior2: DefenceWarrior = warrior as DefenceWarrior
warrior2.defence()
'# 1. Language > 🔰 Kotlin' 카테고리의 다른 글
Kotlin # 접근제한자/예외처리 (0) | 2022.07.01 |
---|---|
Kotlin # 클래스/상속 (0) | 2022.06.29 |
Kotlin # 함수/람다식/흐름제어/반복문 (0) | 2022.06.29 |
Kotlin # text 보여주는 방법 (0) | 2022.06.29 |
Kotlin # Android개발 전 사전 준비 (0) | 2022.06.29 |