본문 바로가기

프로그래밍/Kotlin

[Kotlin 요약 정리] 6. 프로퍼티

6. 프로퍼티

1) 프로퍼티

- 최상위 레벨 변수 혹은 클래스 변수에는 함수(Getter, Setter)가 내장되어 있기 때문에 프로퍼티라고 부름 (지역변수 제외)

- get(), set() 함수 내부에서는 프로퍼티 값을 field로 접근

- val로 선언한 프로퍼티는 set() 함수 정의 불가, get()함수에서 초기화하면 초기값을 지정하지 않아도 됨

- var로 선언한 프로퍼티는 get() 함수를 정의하더라도 초기값을 반드시 명시해야 함

 

class Member constructor(name: String, age: Int){

   var name: String = ""

       get() = field

       set(value) { field = "Mr. " + value }

   var age: Int = 0

       get() = field

       set(value) { field = value }

   val group: Int

       get() = 1

   init{

       this.name = name

       this.age = age

   }

}



fun main() {

   val member = Member("Lee", 20)

   println("${member.name}, ${member.age}, ${member.group}")

   member.name = "Park"

   println("${member.name}, ${member.age}, ${member.group}")

}

// 결과

Mr. Lee, 20, 1

Mr. Park, 20, 1

 

2) lateinit

- 프로퍼티는 선언과 동시에 초기화되어야 하지만 lateinit 예약어를 사용하면 초기화를 미룰 수 있다.

- 제약 조건

var로 선언한 프로퍼티에만 사용 가능

클래스 몸체에 선언한 프로퍼티에만 사용 가능

사용자 정의 getter/setter를 사용 불가

null 허용 불가

기초 타입 프로퍼티에 사용 불가

 

class LateInitTest {

   lateinit var property1: String

   lateinit var property2: Date

   constructor()

   constructor(property1: String, property2: Date){

       this.property1 = property1

       this.property2 = property2

   }

   override fun toString(): String {

       return "$property1, $property2"

   }

}



fun main() {

   val cls1 = LateInitTest()

   val cls2 = LateInitTest("a", Date())

//    println(cls1.toString()) // 에러!

   println(cls2.toString())



   cls1.property1 = "b"

   cls1.property2 = Date()

   println(cls1.toString())

}
// 결과
a, Tue Apr 09 11:02:33 KST 2019
b, Tue Apr 09 11:02:33 KST 2019



3) by lazy

- 프로퍼티 이용 시점에 프로퍼티를 초기화하는 방법

- 제약 조건

호출 시점에 초기화

val로 선언한 프로퍼티에만 사용 가능

클래스 몸체 이외에 최상위 레벨에서 사용 가능

기초 타입에도 사용 가능

 

class LazyEx constructor(code: Boolean){

   val gender: String by lazy {

       println("gender by lazy")

       if(code) "Female" else "Male"

   }

   val group: String by lazy {

       println("group by lazy")

       "First"

   }



   override fun toString(): String = "$gender, $group"

}



fun main() {

   val lazyEx1 = LazyEx(true)

   val lazyEx2 = LazyEx(false)

   println(lazyEx1.toString())

   println(lazyEx2.toString())

}

// 결과

gender by lazy

group by lazy

Female, First

gender by lazy

group by lazy

Male, First



4) by Delegates.observable

- 프로퍼티 값 변경 시에 정의된 코드 실행 가능

 

class BdoEx{

   var pr: String by Delegates.observable("init") { props, old, new ->

       println("props: $props, old: $old, new: $new")

   }

}



fun main() {

   val ex = BdoEx()

   ex.pr = "a"

   ex.pr = "b"

   ex.pr = "c"

}

// 결과
props: var BdoEx.pr: kotlin.String, old: init, new: a
props: var BdoEx.pr: kotlin.String, old: a, new: b
props: var BdoEx.pr: kotlin.String, old: b, new: c