TIL

아이템 36 상속보다는 컴포지션을 사용하라

간단한 행위 재사용

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)
		}
}
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)
		}
}

오버라이딩 제한하기

open class Parent {
	fun a() { }
	open fun b() { }
}

class Child: Parent() {
	override fun a() { } // 오류
	override fun b() { }
}
open class Child: Parent() {
	final override fun b() { }
}