코틀린 sealed class

Koder·2023년 1월 15일
0

자식과 부모의 관계를 나타낼때 필요한것들은 일반 클래스(open class)와 추상 클래스(abstract)와 같은게 대표적으로 떠올릴수 있다.
그러나 위 두가지의 경우는 컴파일시점에 무엇이 누락되었고 사용된지는 알수가 없다.
이런것을 꼼꼼하게 세이프 체크하기 위해서 나온게 코틀린에서 도입된 sealed가 있다.
이는 컴파일 시점에 sealed로 정의된 하위 클래스가 무엇이 있는지 알수 있다.

selaed class의 주의사항은 추상(abstract)와 마찬가지로 자신의 인스턴스는 생성이 불가능하고 같은 패키지의 클래스만 상속 관계를 정의할수 있다.

다음과 같이 sealed에 속한 월별 클래스가 있다고 하자

sealed class Month {
    data class January(val monthIndex: Int, val shortForm: String) : Month()
    data class February(val monthIndex: Int, val shortForm: String, val noOfDays: Int) : Month()
    data class March(val monthIndex: Int, val shortForm: String) : Month()
    data class April(val monthIndex: Int, val shortForm: String) : Month()
    data class May(val monthIndex: Int, val shortForm: String) : Month()
    data class June(val monthIndex: Int, val shortForm: String) : Month()
    data class July(val monthIndex: Int, val shortForm: String) : Month()
    data class August(val monthIndex: Int, val shortForm: String) : Month()
    data class September(val monthIndex: Int, val shortForm: String) : Month()
    data class October(val monthIndex: Int, val shortForm: String) : Month()
    data class November(val monthIndex: Int, val shortForm: String) : Month()
    data class December(val monthIndex: Int, val shortForm: String) : Month()
}

다음과 같이 January만 정의하여 Case를 검사하게되면 그외는 검사를 안하는지 경고를 보여준다.

val m = Month.January(1, "월")
when(m){ // 컴파일 시점에 이곳에서 어떤 case type이 누락되었는지 알수 있다.
	is Month.January -> "${m.monthIndex}${m.shortForm}"
}

<<경고메시지>>: January외에 다른 Type이 누락되었으니 추가하는것을 권유한다.

Non exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7, 
add 'is April', 'is August', ... branches or 'else' branch instead

이정도 요약하여 정리를 해보면 어느때에 sealed를 쓰면 되는지 감이 잡힌것 같다.
필요한 타입 몇가지만 추출하고 그외는 else 처리를 할꺼라면 굳이 필요는 없다.
중요한곳에서 모두 strict하게 완벽하게 처리할일이 있다면 사용시 매우 좋을것이다.

abstract는 새로운 클래스가 추가될수 있는 가능성이 존재하지만
sealed의 경우는 이를 제한하고 만일 추가 되어도 서브 클래스를 제어할수 있기에 예방가능함

profile
일단 적고 보자

0개의 댓글