[kotlin] delegation

할렐루카·2024년 5월 25일
0

kotlin진심펀치

목록 보기
5/6

Delgation 말 그대로 위임한다는 뜻이다.

interface Base {
    fun print()
}

class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

class Derived(b: Base) : Base by b

fun main() {
    val b = BaseImpl(10)
    Derived(b).print()
}

위의 코드의 결과는 10이다 Derived의 구현을 Base를 구현한 b에게 맡기고 b가 정의한 print()대로 출력된다.

interface Base {
    fun printMessage()
    fun printMessageLine()
}

class BaseImpl(val x: Int) : Base {
    override fun printMessage() { print(x) }
    override fun printMessageLine() { println(x) }
}

class Derived(b: Base) : Base by b {
    override fun printMessage() { print("abc") }
}

fun main() {
    val b = BaseImpl(10)
    Derived(b).printMessage()
    Derived(b).printMessageLine()
}

그럼 구현을 맡겨놓고 자기가 원하는 fun은 따로 구현을 한다면? 이것도 예상하기 쉽지만 자신이 override한 함수는 자신이 구현한 대로 출력된다. abc10이 출력된다.

interface Base {
    val message: String
    fun print()
}

class BaseImpl(val x: Int) : Base {
    override val message = "BaseImpl: x = $x"
    override fun print() { println(message) }
}

class Derived(b: Base) : Base by b {
    // This property is not accessed from b's implementation of `print`
    override val message = "Message of Derived"
}

fun main() {
    val b = BaseImpl(10)
    val derived = Derived(b)
    derived.print()
    println(derived.message)
}

그렇다면 이 코드는? 위임한 함수가 바라보는 message만 override 했다. 구현을 맡긴 print() 함수가 override한 message를 바라보는게 자연스러워 보이지만 위임한 함수는 위임한 클래스 내부의 값만 바라 볼 수 있다.

java로 decompile해서 살펴보면 위임한 Base 객체에서 print()를 호출하고 있는 것을 확인할 수 있다. 따라서 결과는

공식문서에 따르면 상속 대신에 위임 패턴을 통해서 필요한 부분만 재정의하여 사용하는 것이 좋은 대안이 되는 경우가 많다고 한다. 또한 kotlin에선 자체적으로 by 키워드를 통해 보일러 플레이트 코드를 피할 수 있다고 한다.

0개의 댓글