Jinhyuk Kim

Software Development Engineer @ Amazon

reniowood at gmail.com
resume

코틀린 공식 문서 번역 - 위임 (Delegation)

2018-04-08

원본 문서: Delegation - Kotlin Progamming Language

코드의 실행 결과는 원본 문서에는 없으나 직접 실행 후 첨부하였다. 실제로 실행해보려면 원본 문서를 참조하기를 바랍니다.


위임에 의한 구현

위임 패턴은 상속 구현의 좋은 대안으로 검증되었다. 코틀린은 위임을 반복적인 코드를 전혀 작성하지 않고도 쓸 수 있도록 제공한다. Derived 클래스는 자신의 모든 공개 멤버를 특정 객체에 위임함으로써 Base 인터페이스를 구현할 수 있다.

interface Base {
    fun print()
}

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

class Derived(b: Base) : Base by b

fun main(args: Array<String>) {
    val b = BaseImpl(10)
    Derived(b).print()
}
// 결과
10

Derived 클래스의 슈퍼타입 목록에 있는 by 구문은 bDerived 객체 내부에 저장되고 컴파일러가 b로 전달되는 Base의 모든 메소드를 생성한다.

위임에 의해 구현된 인터페이스의 멤버 오버라이딩

컴파일러는 위임한 객체의 메소드 대신 override 구현을 사용할 것이다. override fun print() { print("abc") }Derived에 추가하면 프로그램은 print를 호출했을 때 “10”대신 “abc”를 출력한다.

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(args: Array<String>) {
    val b = BaseImpl(10)
    Derived(b).printMessage()
    Derived(b).printMessageLine()
}
// 결과
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(args: Array<String>) {
    val b = BaseImpl(10)
    val derived = Derived(b)
    derived.print()
    println(derived.message)
}
// 결과
BaseImpl: x = 10
Message of Derived