class Progress { // 프로그레스 바를 출력하는 인터페이스
fun showProgress() { /*...*/ }
fun hideProgress() { /*...*/ }
}
class ProfileLoader {
val progress = Progress()
fun load() {
progress.showProgress()
// 프로파일 읽어 들임
progress.hideProgress()
}
}
class ImageLoader {
val progress = Progress()
fun load() {
progress.showProgress()
// 이미지를 읽어 들임
progress.hideProgress()
}
}
class RobotDog : Dog() {
override fun bark() {
print("robot bark!")
}
override fun sniff() { // 로봇 강아지는 냄새를 맡게 하지 못하고 싶음
throw Error("Operation not supported")
}
}
class CounterSet<T> {
private val innerSet = HashSet<T>()
var elementsAdded: Int = 0
private set
fun add(element: T) {
elementsAdded++
innserSet.add(element)
}
fun addAll(elements: Collection<T>) {
elementsAdded += elements.size
innserSet.addAll(elements)
}
}
CounterSet
은 더 이상 Set
이 아니기 때문에 다형성이 사라진다.Set
타입임을 유지하고 싶다면 위임패턴을 사용하면 된다.
super
의 메서드가 아닌, 컴포지션으로 가지고 있는 인스턴스에게 위임하는 패턴이다.class CounterSet<T> : MutableSet<T> {
private val innerSet = HashSet<T>()
var elementsAdded: Int = 0
private set
override fun add(element: T) { // 포워딩 메서드
elementsAdded++
innserSet.add(element)
}
override fun addAll(elements: Collection<T>) {
elementsAdded += elements.size
innserSet.addAll(elements)
}
// ... 오버라이드할 메서드가 많다
}
class CounterSet<T>(
private val innserSet: MutableSet<T> = mutableSetOf()
) : MutableSet<T> by innserSet {
var elementsAdded: Int = 0
private set
override fun add(element: T) { // 포워딩 메서드
elementsAdded++
innserSet.add(element)
}
override fun addAll(elements: Collection<T>) {
elementsAdded += elements.size
innserSet.addAll(elements)
}
}
final
을 사용하면 된다.open
키워드를 활용할 수 있다.
open
클래스는 open
메서드만 오버라이드할 수 있다.open class Parent {
fun a() { }
open fun b() { }
}
class Child: Parent() {
override fun a() { } // 오류
override fun b() { }
}
final
을 붙일 수도 있다.open class Child: Parent() {
final override fun b() { }
}