https://android.jlelse.eu/kotlin-sealed-classes-enum-2-0-1d8addd00602를 번역한 내용입니다.
예를들어 일요일, 월요일, 화요일 등 요일에 대한 정보를 갖는 객체 집합을 만들기 위해 enum클래스를 사용할 수 있다.
enum class Days(dayNo: Int) { SUNDAY(0), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6) }
왜 sealed class가 필요할까 라는 생각이 들텐데 그전에 enum의 제약사항에 대해 알아보자
- 각각의 enum 상수에 대해 하나의 인스턴스만 생성할 수 있다. 예를들면 일요일은 항상 dayNo가 0인 상태이다.
- 주어진 enum 에 대한 상태를 변경할 수 없다. 예를 들어, 어떤 나라에서는 한 주의 시작을 월요일로 생각할 수도 있다. 그렇다면 Monday의 dayNo를 0으로 설정해야 하지만 enum은 그러한 기능을 제공하지 않는다.
- enum에 대한 서브클래스를 생성할 수 없다.
Sealed 클래스는 위의 제약사항을 넘어서는 enum의 확장판 또는 enum 2.0 버전이라고 볼 수 있다.
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() }
Month는 Sealed 클래스 이고 Month의 서브클래스들을 내포 하고 있다.
Sealed 클래스의 기본원칙은 다음과 같다.
- Sealed클래스는 클래스이름 앞에 sealed 키워드를 붙여 만들 수 있다.
- Sealed클래스의 서브클래스들은 반드시 같은 파일내에 선언되어야 한다.
- Sealed클래스 기본적으로 abstract 클래스이다
- Sealed클래스는 private 생성자만 갖는다
- Sealed클래스의 서브클래스를 상속한 클래스들은 아무대나 존재해도 상관없다. 같은 파일 내에 없어도 된다.
Sealed클래스를 사용했을 때 얻을 수 있는 이점들을 살펴보자
- 각각의 Sealed클래스의 서브클래스에 대해 여러개의 인스턴스를 생성할 수 있다. 그렇기 때문에 상태값을 변경할 수 있다. 예를들어 두가지 February객체(19년 2월과 20년 2월) 를 생성하고, 비교할 수 있다.
- Sealed클래스의 계층을 생성할 수있다.
- ‘when’ 표현식을 사용한다면 sealed클래스에서는 else 절을 구현할 필요 없다.
0개의 댓글