Delegation 패턴은 상속 처리의 좋은 대안으로, Kotlin은 네이티브 코드에 보일러 플레이트 코드가 필요 없는 이 패턴을 지원한다.
아래 코드에서 클래스 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(){
val b = BaseImpl(10)
Derived(b).print()
}
//result: 10
Derived의 상위 타입 목록에 있는 by는 Derived의 객체 내부에 b가 저장되고 컴파일러가 b로 전달되는 Base의 모든 메소드를 생성한다.
Delegation으로 구현된 인터페이스의 Overriding
컴파일러는 위임 오브젝트 내의 구현이 아닌 override된 구현을 적용한다.
Derived에서 override fun printMessage() { print("abc") }를 호출하면 printMessage의 결과는 10이 아닌 abc를 출력한다.
interface Base{
fun printMessage()
fun printMessageLine()
}
class BaseImpl(val x: Int): Base{
override fun printMessage() { print(x) }
override fun printMessageLine() { print(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()
}
//result: 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)
}
//result: BaseImpl: x = 10
Message of Derived
'Kotlin' 카테고리의 다른 글
[Kotlin] Object (0) | 2022.03.25 |
---|---|
[Kotlin] Delegated Properties (0) | 2022.03.23 |
[Kotlin] 코틀린의 시퀀스(Sequence) (0) | 2022.01.24 |
[Kotlin] 코틀린에서 RxJava와 Coroutine (0) | 2022.01.06 |
[Kotlin] Coroutine 동기화 처리 (0) | 2021.12.21 |