Skip to content

위임

위임 패턴(Delegation pattern)은 구현 상속(implementation inheritance)에 대한 좋은 대안임이 입증되었으며, Kotlin은 상용구 코드(boilerplate code)가 전혀 필요 없이 이를 기본적으로 지원합니다.

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 객체 내부에 내부적으로 저장되며 컴파일러가 Base의 모든 메서드를 b로 전달하도록 생성한다는 것을 나타냅니다.

위임으로 구현된 인터페이스 멤버 오버라이드하기

오버라이드(Overrides)는 예상대로 작동합니다. 컴파일러는 위임 객체에 있는 구현 대신 사용자의 override 구현을 사용합니다. 만약 Derivedoverride fun printMessage() { print("abc") }를 추가한다면, 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)
}

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