1. 위임 (Delegation)
class A와 class B가 인터페이스C를 implement 했다고 치자.
A와 B는 아무런 관계가 없다. 다만 C를 implement 받았을 뿐..
그런데 A가 갖고있는 기능을 그대로 B에게 양도해서 B를 정의하고 싶다면??
이런식으로 클래스의 기능을 양도해서 별도의 클래스를 작성하는 것을 위임이라고한다.
fun main() {
val p = Person("아테나",10)
println("==========================")
p.show()
println(p.message)
val s = Student(p)
println("==========================")
s.show()
println(s.message)
}
interface Human {
val name : String
val age : Int
val message : String
fun show()
}
class Person(val nm : String, val ag : Int) : Human{
override val name = nm
override val age = ag
override val message = " 이름 : $name 나이 : $age "
override fun show(){
println(message)
}
}
class Student(human : Human) : Human by human{
override val message = "저는 ${human.name} 이고 나이는 ${human.age}입니다. "
}
//output
==========================
이름 : 아테나 나이 : 10
이름 : 아테나 나이 : 10
==========================
이름 : 아테나 나이 : 10
저는 아테나 이고 나이는 10입니다.
Human by human를 주목!!
Student가 인터페이스를 implement받을때 !!
파라미터로 받은 human객체에 의해 Human인터페이스를 implement한다는 뜻이다.
s.show()를 호출하면 Student 클래스의 show 함수가 호출되며 => Person의 show() ,
s.message를 출력하면 Student 클래스의 message 값을 출력합니다.
2. 프로퍼티 감시하기 - observable
프로퍼티 값이 바뀌면 그걸 계속 쳐다보는 observable을 이용하여 처리한다.
import kotlin.properties.Delegates
Delegates클래스는 kotlin.properties 패키지안에 속해있다.Delegates안에는 observable이라는 메소드가 준비되어있다.
import kotlin.properties.Delegates
fun main() {
val p = Person("코코")
p.show()
p.name = "하나"
p.show()
}
class Person(name : String){
var name : String by Delegates.observable("<no name>")
//()에는 초기값을 집어넣는다 : "<no name>"
{ //KProperty라는 클래스의 객체, oldValue, newValue를 던진다.
property, oldValue, newValue ->
//여기서 리턴값은 ReadWriteProperty라는 클래스의 객체로써, by 인스턴트해서 읽어옴
println("${property.name} ${oldValue} => ${newValue}")
}
init{
this.name = name
}
fun show(){
println("내 이름은 $name 입니다. ")
}
}
//output
name <no name> => 코코
내 이름은 코코 입니다.
name 코코 => 하나
내 이름은 하나 입니다.
3. 프로퍼티 변경 이벤트를 다른애들에게 넘기자
코틀린 프로퍼티는, set/get으로 값을 읽고쓰는것을 제어할 수있다.
이 읽고쓰는 조작을 다른애들에게 위탁해서 외부로부터 프로퍼티조작을 제어하는것도 가능하다.
이렇게 용이되어있는 기능을 외부애들에게 위탁하여 처리시키는것을 위임(delegation)이라고 한다.
import kotlin.reflect.KProperty
fun main() {
val p = Person("아테나",40)
p.show()
p.name = "하나"
p.age = 10
p.show()
}
class NameDelegate {
private var value : String = ""
operator fun getValue(thisRef : Any? , property : KProperty<*>) : String{
println("***[${property.name}] get '${this.value}'.*** ")
return value
}
operator fun setValue(thisRef : Any?, property : KProperty<*>, value : String) {
println("***[${property.name}] set '${this.value}' -> '${value}'.*** ")
this.value = value
}
}
class AgeDelegate {
private var value : Int = 0
operator fun getValue(thisRef : Any?, property : KProperty<*>) : Int {
println("***[${property.name}] get '${this.value}'.*** ")
return value
}
operator fun setValue(thisRef : Any?, property : KProperty<*>, value : Int) {
println("***[${property.name}] set '${this.value}' -> '${value}'.*** ")
this.value = value
}
}
class Person(name : String, age : Int){
var name : String by NameDelegate()
var age : Int by AgeDelegate()
init{
this.name = name
this.age = age
}
fun show(){
println("<<< ${name} $age >>>")
}
}
//output
***[name] set '' -> '아테나'.***
***[age] set '0' -> '40'.***
***[name] get '아테나'.***
***[age] get '40'.***
<<< 아테나 40 >>>
***[name] set '아테나' -> '하나'.***
***[age] set '40' -> '10'.***
***[name] get '하나'.***
***[age] get '10'.***
<<< 하나 10 >>>
4. 연산자 오버로드
프로퍼티의 Delagetes class에서 작성된 메소드에는, operator라는 키워드가 사용된다.
이건, 연산자 오버로드라는것에도 사용되는 키워드이다.
새로운 Person class를 만들었다치자. 그때 Person객체끼리를 +해서 더할순없다.
그러나 연산자 오버로드를 사용함으로써 Person + Person 연산이 가능해진다!
c객체 안에는 a+b를 내포하고 있다.
import kotlin.properties.Delegates
fun main() {
val a = Shopping("banana", 2000)
val b = Shopping("orange", 3000)
val c = Shopping("apple", 4000)
c += a+b
c.show()
}
class Shopping(name : String, price : Int){
class Item(name : String, price : Int){
val name = name
val price = price
}
val items = mutableListOf<Item>()
init{
items.add(Item(name,price))
}
fun show(){
println("<< Shopping List >>")
for(item in items) println("${item.name}은 ${item.price}")
println()
}
operator fun plus(shopping : Shopping) : Shopping{
val s = Shopping("",0)
s.items.removeFirst()
s.items.addAll(items)
s.items.addAll(shopping.items)
return s
}
operator fun plusAssign(shopping : Shopping){
items.addAll(shopping.items)
}
}
//output
<< Shopping List >>
apple은 4000
banana은 2000
orange은 3000
'Kotlin' 카테고리의 다른 글
Kotlin14. null 문제, 스코프함수 (0) | 2023.08.13 |
---|---|
Kotlin13. class의 다른 확장 - Pair, 확장메소드/프로퍼티.. (0) | 2023.08.13 |
Kotlin11. interface, abstract, Singleton (0) | 2023.08.13 |
Kotlin10. class와 OOP (0) | 2023.08.06 |
Kotlin9. 재귀함수, 꼬리재귀 (0) | 2023.08.01 |