실무 프로젝트로 배우는 Kotlin & Spring/코틀린 고급

실드 클래스

webmaster 2022. 10. 9. 18:01
728x90

하나의 상위 클래스, 인터페이스에서 하위 클래스 정의를 제한할 때 사용한다

sealed 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}를 사용합니다.")
    }
}

object OtherDeveloper: Developer(){
    override val name: String = "익명"
    override fun code(language: String) {
        TODO("Not yet implemented")
    }
}

data class AndroidDeveloper(override val name: String): Developer(){
    override fun code(language: String) {
        println("저는 안드로이드 개발자입니다 ${language}를 사용합니다.")
    }
}

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 구문이 없게 되면, 컴파일 오류가 발생한다
        //컴파일러가 Developer 를 구현한 것이 2가지 밖에 없다는 것을 알 수가 없기 떄문에 -> sealed 사용
        //sealed 클래스는 컴파일러가 컴파일 시점에, 하위 클래스가 2가지 타입만 있다는 것을 알고 컴파일 오류가 나지 않도록 한다.
        //sealed 클래스의 제약은 같은 패키지, 같은 모듈에 있어야지만, 컴파일러가 파악할 수 있다.
        //is OtherDeveloper -> pool[developer.name] = developer //새로운 클래스를 추가하게 되면, 이 코드가 없으면 컴파일 오류가 난다.
        //else -> println("지원하지 않는 개발자 종류입니다.") //Android 개발자를 추가하면, 여기서 같이 걸리게 된다 -> 개발자는 OtherDeveloper만 걸리면 좋겠다고 생각했음
        is AndroidDeveloper -> pool[developer.name] = developer
        is OtherDeveloper -> pool[developer.name] = developer
    }
    fun get(name: String) = pool[name]
}

fun main() {
    val backendDeveloper = BackendDeveloper(name = "토니")
    DeveloperPool.add(backendDeveloper)

    val frontendDeveloper = FrontendDeveloper(name = "카즈야")
    DeveloperPool.add(frontendDeveloper)

    val androidDeveloper = AndroidDeveloper(name = "토마스")
    DeveloperPool.add(androidDeveloper)

    println(DeveloperPool.get("토니"))
    println(DeveloperPool.get("카즈야"))
    println(DeveloperPool.get("토마스"))
}
  • 컴파일러가 sealed를 사용하지 않는다면, 컴파일 시점에 Developer를 상속한 하위 클래스가 몇 개인지 알지 못해, else를 구현하지 않으면, 컴파일 오류를 낸다.
  • sealed 키워드를 쓰게 되면 컴파일 오류가 더이상 생기지 않는다.
  • 실드 클래스는 하위 클래스를 제한 조건에 따라 정의해야하고, 이렇게 만들어진 실드 클래스의 하위 클래스는 컴파일러가 컴파일 시점에 판단할 수 있다.
    • 제한 조건으로 코틀린 1.6 버전 기준 같은 패키지, 모듈안에 있는 경우에만 하위 클래스를 정의할 수 있다.
  • else를 사용하게 된다면 예상치 못한 버그(안드로이드 개발자를 추가했을 경우)를 경험 하기에 적절하게 실드 클래스를 선언하여 버그를 줄이는 것이 중요하다.
728x90

'실무 프로젝트로 배우는 Kotlin & Spring > 코틀린 고급' 카테고리의 다른 글

제네릭  (0) 2022.10.16
확장 함수  (0) 2022.10.09
싱글톤과 동반객체  (0) 2022.10.09
데이터 클래스  (0) 2022.10.08
컬렉션  (0) 2022.10.08