[코틀린기초] 28. 위임(delegation)

비유하자면 직원이 사장의 권한을 위임받아 사장의 권한을 행사하는 것

 <var | val | class> 프로퍼티 혹은 클래스 이름 : 자료형 by 위임자

## 위임을 사용하는 이유?

## 다른 클래스 멤버를 사용하도록 위임

 interface Animal{
  fun eat(){...}
 }
 
 class Car : Animal{}
 val cat = Cat()
 class Robot : Animal by cat  //  Animal의 정의된 cat의 모든 멤버를 Robot에 위임

## 예제 코드

 interface Car{
  fun go(): String
 }
 
 class VanImpl(val power: String): Car{
  override fun go() = "는 짐을 적재하며 $power 마력을 가집니다."
 }
 
 class SportImpl(val power: String): Car{
  override fun go() = "는 경주용에 사용되며 $power 마력을 가집니다."
 }
 
 class CarModel(val model: String, impl: Car): Car by impl {
  fun carInfo(){
    println("$model ${go()}") // 참조 없이 각 인터페이스 구현 클래스의 go를 접근
  }
 }
 
 fun main(){
  val myDamas = CarModel("Damas 2010", VanImpl("100마력"))
  val my350z = CarModel("350Z 2008", SportImpl("350마력"))
  
  myDamas.carInfo() // carInfo에 대한 다형성을 나타냄
  my350z.carInfo()
 }
 

## 프로퍼티 위임과 by lazy

#### 동작 분석

## observable과 vetoable의 위임

#### observable 사용 예제

 class User{
 // observable은 값의 변화를 감시하는 일종의 콜백 루틴
  var name: String by Delegates.observable("NONAME"){ // 프로퍼티를 위임, NONAME은 초깃값
    prop, old, new -> // 람다식 매개변수로 프로퍼티, 기존 값, 새로운 값
    println("$old -> $new") // 이벤트가 발생할 때만 실행됨
  }
 }
 
 fun main(){
  val user = User()
  user.name = "Kildong" // 값이 변경되므로 첫 이벤트 발생
  user.name = "Dooly" // 값이 변경되므로 두번째 이벤트 발생
 }

#### vetoable 사용 예제

 fun main(){
    var max: Int by Delegates.vetoable(0){
      prop, old, new ->
      new > old // 조건에 맞지 않으면 거부권 행사
    }
    
    println(max)  // 0
    max = 10
    println(max) // 10
    
    max= 5  // 거부됨
    println(max) // 10
 }