코틀린에서는 인터페이스를 구현할 때 by 키워드를 이용해 인터페이스에 대한 구현을 다른 객체에 위임할 수 있습니다
예제
class CountingSet<T>(
private val innerSet: MutableCollection<T> = HashSet(),
): MutableCollection<T> {
override val size: Int = innerSet.size
override fun contains(element: T): Boolean = innerSet.contains(element)
override fun containsAll(elements: Collection<T>): Boolean = innerSet.containsAll(elements)
override fun isEmpty(): Boolean = innerSet.isEmpty()
override fun iterator(): Iterator<T> = innerSet.iterator()
// ... 기타 수많은 메소드
}
set에 add한 횟수를 카운팅해서 저장하는 클래스를 만든다고 해보겠습니다
카운터를 만들기 전에, 아무 동작도 추가되지 않은 빈 껍데기 클래스를 만든다고 해도 위처럼 Collection 인터페이스의 메소드를 오버라이드 해줘야 합니다.
정작 오버라이드 하려는 add, addAll보다 boilerplate의 코드가 더 많습니다
class CountingSet<T>(
private val innerSet: MutableCollection<T> = HashSet(),
): MutableCollection<T> by innerSet {
private var counter = 0
override fun add(element: T): Boolean {
++counter
return innerSet.add(element)
}
override fun addAll(elements: Collection<T>): Boolean {
counter += elements.size
return innerSet.addAll(elements)
}
}
by 키워드를 사용해 메소드 동작을 innerSet에 맡기면 이런식으로 다른 메소드의 동작을 위임시킬 수 있습니다
interface Movable {
fun move(x: Int, y: Int)
}
interface Attackable {
fun attack(target: Any)
}
class OnFoot : Movable {
override fun move(x: Int, y: Int) = println("($x, $y)로 걸어감")
}
class WithGaussRifle : Attackable {
override fun attack(target: Any) = println("${target}에게 가우스 소총 공격")
}
class WithFlameThrower : Attackable {
override fun attack(target: Any) = println("${target}에게 화염방사기 공격")
}
class Marine : Movable by OnFoot(), Attackable by WithGaussRifle()
class Firebat : Movable by OnFoot(), Attackable by WithFlameThrower()
class HeroMarine(private val _marine: Marine) :
Movable by _marine,
Attackable by _marine {
override fun attack(target: Any) {
println("영웅마린의 공격!")
return _marine.attack(target)
}
}
위처럼 여러 인터페이스를 위임하는 것도 가능합니다 (https://stackoverflow.com/q/62685097/4295499)
Reference
- https://kotlinlang.org/docs/delegation.html
- https://en.wikipedia.org/wiki/Delegation_pattern
- Kotlin in Action 4.3.3
반응형
'프로그래밍 > Kotlin' 카테고리의 다른 글
[Kotlin] count, size 함수 (kotlin in action) (0) | 2022.04.02 |
---|---|
[Kotlin] 람다 (lambda) (0) | 2022.03.27 |
[Kotlin] local function (로컬 함수) (0) | 2022.03.26 |
[Kotlin] infix call (중위 호출) (0) | 2022.03.26 |
[Kotlin] vararg(가변인자), spread operator (0) | 2022.03.21 |