아래와 같이 Developer라는 추상클래스를 상속받은 Backend, Frontend 클래스가 있다.
abstract class Developer {
abstract val name: String
abstract fun code(language: String)
}
data class BackendDeveloper(override val name: String) : Developer() {
override fun code(language: String) {
println(" ${language} ")
}
}
data class FrontendDeveloper(override val name: String) : Developer() {
override fun code(language: String) {
println(" ${language} ")
}
}
그 다음은 생성된 Developer 객체를 보관하는 DeveloperPool을 만든다.
object DeveloperPool {
val pool = mutableMapOf<String, Developer>()
fun add(developer: Developer) = when (developer) {
is BackendDeveloper -> pool[developer.name] = developer
is FrontendDeveloper -> pool[developer.name] = developer
else -> {
println(" ")
}
}
fun get(name: String) = pool[name]
}
fun main() {
val backendDeveloper = BackendDeveloper(name = "토니")
DeveloperPool.add(backendDeveloper)
val frontendDeveloper = FrontendDeveloper(name = "저스틴)
DeveloperPool.add(frontendDeveloper)
println(DeveloperPool.get("토니"))
println(DeveloperPool.get("저스틴"))
}
위는 겉보기에는 문제가 없어보인다.
만약 else를 삭제하면 무슨일이 발생할까?
when식에서 컴파일 오류가 발생한다.
컴파일러 입상에서는 Developer를 상속한 하위클래스가 몇 개나 되는지 어떤 클래스가 상속받고 있는지 알 방법이 없다.
object DeveloperPool {
val pool = mutableMapOf<String, Developer>()
fun add(developer: Developer) = when (developer) { //컴파일 오류
is BackendDeveloper -> pool[developer.name] = developer
is FrontendDeveloper -> pool[developer.name] = developer
}
fun get(name: String) = pool[name]
}
이때 abstract키워드를 sealed로 변경해보자.
sealed class Developer {
abstract val name: String
abstract fun code(language: String)
}
when 식에 else가 없음에도 오류가 발생하지 않는다.
실드 클래스는 하위 클래스를 제한 조건에 따라 정의해야하고 이렇게 만들어진 실드 클래스의 하위 클래스는 컴파일러가 컴파일 시점에 판단할 수 있다.
제한 조건으로 최신 코틀린 1.6 버전 기준 같은 패키지 또는 모듈 안에 있는 경우에만 하위 클래스를 정의할 수 있다.
실드 클래스
실드 클래스를 쓰는 이유
else
를 삭제하면 무슨일이 발생할까?abstract
키워드를sealed
로 변경해보자.제한 조건에 따라 정의해야하고
이렇게 만들어진 실드 클래스의 하위 클래스는컴파일러가 컴파일 시점에 판단할 수 있다.