Skip to content

위임

위임 패턴(Delegation pattern)은 구현 상속의 좋은 대안임이 입증되었으며, 코틀린은 불필요한 상용구 코드 없이 이를 기본적으로 지원합니다.

Derived 클래스는 모든 공개 멤버를 지정된 객체에 위임함으로써 Base 인터페이스를 구현할 수 있습니다:

kotlin
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 base = BaseImpl(10)
    Derived(base).print()
}

Derived의 상위 타입 목록에 있는 by 절은 bDerived 객체 내부에 저장되며, 컴파일러가 b로 전달되는 Base의 모든 메서드를 생성함을 나타냅니다.

위임을 통해 구현된 인터페이스 멤버 재정의

재정의는 예상대로 작동합니다. 컴파일러는 위임 객체에 있는 구현 대신 사용자가 override한 구현을 사용합니다. override fun printMessage() { print("abc") }Derived에 추가하면, printMessage가 호출될 때 프로그램은 10 대신 abc를 출력할 것입니다:

kotlin
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 base = BaseImpl(10)
    Derived(base).printMessage()
    Derived(base).printMessageLine()
}

하지만 이런 식으로 재정의된 멤버는 위임 객체의 멤버로부터 호출되지 않는다는 점에 유의하십시오. 위임 객체의 멤버는 인터페이스 멤버의 자체 구현에만 접근할 수 있습니다:

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

class BaseImpl(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)
}

위임 프로퍼티에 대해 더 알아보세요.