코틀린 프로퍼티 (Property)
- 변수 선언과 접근 메서드를 모두 가진다.
- 접근 메서드를 따로 만들지 않아도 내부적으로 생성한다.
게터(Getter)와 세터(Setter) 구성
- 코틀린은 자바와 다르게 모든 변수에 대한 접근 메서드(게터 + 세터)를 만들지 않아도 기본 생성해준다.
- val인 경우 불변형이기 때문에 게터(Getter)만 설정할 수 있다.
fun main() {
val coffee = Coffee("Americano", 4000)
// Getter에 의한 값 얻기
val coffeeName = coffee.name
// Setter에 의한 값 설정
coffee.price = 5000
}
// 접근 메서드는 내부적으로 생성
class Coffee(name: String, price: Int) {
var name: String = name
var price: Int = price
}
- 기본 게터와 세터를 직접 지정할 수 있다.
class Coffee(name: String, price: Int) {
var name: String = name
get() = field
set(value) {
field = value
}
var price: Int = price
get() = field
set(value) {
field = value
}
}
지연 초기화
- 변수나 객체의 값은 생성할 때 초기화가 필요하다.
- 하지만 값을 나중에 나타나는 경우에는 초기화를 나중에 할 필요가 있다.
- 이 때, lateinit과 lazy키워드를 사용한다.
lateinit
- lateinit 키워드를 사용하면 프로퍼티에 값이 바로 할당되지 않아도 된다.
- 의존성이 있는 초기화나 단위 테스트 코드를 작성 시 사용한다.
- var로 선언된 프로퍼티만 사용 가능
- 프로퍼티에 게터와 세터를 사용할 수 없다.
fun main() {
val coffee = Coffee()
coffee.name = "Americano"
println(coffee.name)
}
class Coffee {
lateinit var name: String
}
/* 출력
Americano
*/
lazy
- 호출할 때 by lazy { }를 통해 블록 부분의 초기화를 한다.
- val로 선언된 프로퍼티만 사용 가능하며 val이기 때문에 값을 다시 변경할 수 없다.
fun main() {
val coffee = Coffee()
coffee.flow()
}
class Coffee {
init {
println("init block")
}
private val name by lazy {
println("lazy init")
"Americano"
}
fun flow() {
println("not init")
println("one ${name}")
println("two ${name}")
}
}
/* 출력
init block
not init
lazy init
one Americano
two Americano
*/
lazy는 3가지 모드를 지정할 수 있다.
- SYNCHRONIZED - 락을 사용하여 단일 쓰레드만 사용하는 것을 보장한다. (기본 값)
- PUBLICATION - 여러 곳에서 호출 가능하지만 처음 초기화된 후 반환 값을 사용한다.
- NONE - 락을 사용하지 않아 빠르지만 다중 쓰레드가 접근 가능. (값의 일관성 보장할 수 없음)
private val name by lazy(mode = LazyThreadSafetyMode.NONE) {
// 단일 쓰레드의 사용일 때
}
By
- by 키워드는 디자인 패턴 중 Delegate Pattern을 쉽게 구현할 수 있게 도와준다.
- 위탁자 -> 수탁자의 형태이며 일의 책임 및 처리를 다른 클래스 또는 메서드에게 넘긴다. (위임)
- 다른 클래스의 기능을 사용하지만 그 기능을 변경하지 않을 경우 상속대신 위임을 활용한다.
- 위임을 활용하면 객체가 변경될 때 다른 객체에 미치는 영향이 적어진다.
- interface 타입의 위임만 가능한다.
interface Coffee {
fun getPrice() { println("4000") }
}
class Americano: Coffee {}
var americano = Americano()
// americano의 모든 멤버를 Latte에 위임
class Latte: Coffee by americano
- 프로퍼티 표준 위임 함수인 observable()과 vetoable()함수를 사용할 수 있음
// observable()
// 프로퍼티 내용이 변경될 때 수행할 작업을 정의할 수 있다.
// 콜백과 동일하다.
fun main() {
var observable = Observable()
observable.num = 2
observable.num = 3
}
class Observable {
var num : Int by Delegates.observable(1) {
kProperty: KProperty<*>, old: Int, new: Int ->
println("${old} -> ${new}")
}
}
/* 출력
1 -> 2
2 -> 3
*/
// vetoable()
// observable()과 동일하지만 조건에 맞지 않으면 새로운 값 할당을 거부할 수 있다.
// true -> 새로운 값 할당
// false -> 새로운 값 할당 거부
fun main() {
var vetoable = Vetoable()
println(vetoable.num)
vetoable.num = 0
println(vetoable.num)
vetoable.num = 20
println(vetoable.num)
}
class Vetoable {
var num : Int by Delegates.vetoable(10) {
kProperty: KProperty<*>, old: Int, new: Int ->
println("${old} - > ${new} , check : ${old > new}")
old > new
}
}
/* 출력
10
10 - > 0 , check : true
0
0 - > 20 , check : false
0
*/
'Kotlin' 카테고리의 다른 글
[Kotlin] 추상 클래스 (0) | 2023.05.25 |
---|---|
코틀린 정적 변수 (0) | 2023.03.14 |
코틀린 클래스와 객체 (0) | 2023.02.14 |
코틀린 함수 (0) | 2023.02.13 |
코틀린 조건문과 반복문 (0) | 2023.02.10 |