위임
이 페이지의 마지막 수정: 2024년 8월 19일
...
대리자(위임) 패턴은 구현 상속 확장1의 좋은 대안으로 증명되어왔으며, Kotlin 은 이를 어떠한 보일러플레이트도 필요 없는 형태로 지원합니다.
[1] 원문: implementation inheritance
Derived
클래스는 Base
인터페이스의 모든 멤버를 주어진 오브젝트에서 위임받아 구현될 수 있습니다:
1interface Base {
2 fun print()
3}
4
5class BaseImpl(val x: Int) : Base {
6 override fun print() { print(x) }
7}
8
9class Derived(b: Base) : Base by b
10
11fun main() {
12 val base = BaseImpl(10)
13 Derived(base).print()
14}
15
위의 코드는 아래처럼 출력합니다:
110
2
Derived
클래스의 슈퍼타입 목록에 표기된 by
구문은, b
가 Derived
타입의 오브젝트 내에 내부적으로 저장되며
컴파일러가 모든 Base
의 구성요소들을 b
에게로 위임하게 함을 의미합니다.
위임받은 인터페이스의 멤버를 재정의하기
재정의는 예상하시는 대로 동작합니다: 컴파일러는 override
로 재정의된 함수는 주어진 오브젝트에게 위임하지 않습니다.
만약 Derived
에 override fun printMessage() { print("abc") }
를 추가한다면, printMessage
가 호출될 때 10
대신 abc
가 출력됩니다:
1interface Base {
2 fun printMessage()
3 fun printMessageLine()
4}
5
6class BaseImpl(val x: Int) : Base {
7 override fun printMessage() { print(x) }
8 override fun printMessageLine() { println(x) }
9}
10
11class Derived(b: Base) : Base by b {
12 override fun printMessage() { print("abc") }
13}
14
15fun main() {
16 val base = BaseImpl(10)
17 Derived(base).printMessage()
18 Derived(base).printMessageLine()
19}
20
위의 코드는 아래처럼 출력합니다:
1abc10
2
하지만 기억하세요, 이렇게 재정의된 함수는 위임하려는 오브젝트에서는 호출되지 못합니다. 위임하려는 오브젝트는 그 자신의 구현에만 접근할 수 있으니까요:
1interface Base {
2 val message: String
3 fun print()
4}
5
6class BaseImpl(x: Int) : Base {
7 override val message = "BaseImpl: x = $x"
8 override fun print() { println(message) }
9}
10
11class Derived(b: Base) : Base by b {
12 // 이 프로퍼티는 b 의 'print' 구현에서 접근할 수 없습니다.
13 override val message = "Message of Derived"
14}
15
16fun main() {
17 val b = BaseImpl(10)
18 val derived = Derived(b)
19 derived.print()
20 println(derived.message)
21}
22
위의 코드는 아래처럼 출력합니다:
1BaseImpl: x = 10
2Message of Derived
3
위임된 프로퍼티에 대해서도 자세히 알아보세요.
이 페이지가 도움이 되셨다면, 원문 페이지에 방문해 엄지척을 해주세요!