by
를 사용하여 위임관계를 쉽게 구성할 수 있음.
interface Base { fun say() }
class BaseImpl(private val x: Int) : Base {
override fun say() { println("베이스 클래스 구현 : $x") }
}
class Derived(private val b: BaseImpl) : Base {
override fun say() { b.say() }
}
class Derived2 : Base by BaseImpl(10)
fun main() {
val b = BaseImpl(10)
Derived(b).say() // 베이스 클래스 구현 : 10
Derived2().say() // 베이스 클래스 구현 : 10
}
interface SoundBehavior { fun makeSound() }
class ScreamBehavior : SoundBehavior {
override fun makeSound() = println("Screaming!!!")
}
class RockAndRollBehavior : SoundBehavior {
override fun makeSound() = println("Rock'n'roll!!!")
}
class Person(soundBehavior: SoundBehavior) : SoundBehavior by soundBehavior
fun main() {
Person(ScreamBehavior()).makeSound() // Screaming!!!
Person(RockAndRollBehavior()).makeSound() // Rock'n'roll!!!
}
class CounterSet<T>(
private val innerSet: MutableSet<T> = mutableSetOf()
) : MutableSet<T> by innerSet {
var elementAdded: Int = 0
private set
override fun add(element: T): Boolean {
elementAdded++
return innerSet.add(element)
}
override fun addAll(elements: Collection<T>): Boolean {
elementAdded += elements.size
return innerSet.addAll(elements)
}
fun display(): MutableSet<T> = innerSet
}
fun main() {
val counterList = CounterSet<String>()
counterList.addAll(listOf("A", "B", "C", "D", "E"))
println(counterList.elementAdded) // 5
println(counterList.display()) // [A, B, C, D, E]
}
add
, addAll
함수는 재정의 됐으므로 제외.<aside> 💡 by 키워드는 CounterSet에 MutableSet의 모든 멤버 함수를 자동으로 복사하는 것처럼 동작함. 실제로 복사되진 않고, 호출 시 위임 객체(innerSet)의 해당 함수가 호출됨.
</aside>
// 잔액 관리 클래스
class Balance(val accountNo: Int, var balance: Int)
// 입, 출금 처리
interface Accountable {
fun deposit(acc: Balance, amount: Int)
fun withdraw(acc: Balance, amount: Int)
}
// 입, 출급 구현 클래스
class DWManager : Accountable {
override fun deposit(acc: Balance, amount: Int) { acc.balance = acc.balance + amount }
override fun withdraw(acc: Balance, amount: Int) { acc.balance = acc.balance - amount }
}
// 계좌 관리 클래스
class Agreement(
val accountNo: Int,
val dwManager: Accountable
) : Accountable by dwManager
fun main() {
val dwManager = DWManager()
val b = Balance(1, 0)
val a = Agreement(1, dwManager)
a.dwManager.deposit(b, 1000)
println("계좌번호 : ${a.accountNo}")
println("계좌번호 : ${b.accountNo} 잔액 : ${b.balance}")
a.dwManager.withdraw(b, 500)
println("계좌번호 : ${b.accountNo} 잔액 : ${b.balance}")
}
실행결과
계좌번호 : 1
계좌번호 : 1 잔액 : 1000
계좌번호 : 1 잔액 : 500