(Kotlin) sealed class
1. sealed class
보통 여러 자식 클래스들이 하나의 부모 클래스를 상속하게 되면 컴파일러는 상속하는 자식 클래스가 어떤 클래스인지 모른다.
Kotlin의 sealed class는 부모 클래스를 상속하는 자식 클래스의 종류를 제한하는 특성을 갖는 클래스이다. 또한, sealed class는 같은 패키지에 존재하는 자식 클래스만 상속할 수 있다. 즉, sealed class를 사용하게 되면 동일 파일에 정의되어 있는 자식 클래스 외에 다른 어떤 클래스도 존재하지 않는다는 것을 명시적으로 컴파일러에 알려 컴파일 에러를 없에게 된다.
UI의 상태를 관리하는 클래스를 만든다고 가정해보자.
abstract class UiState
class Loading : UiState
class Running : UiState
...
fun doSomething(uiState: UiState) : Any {
return when (uiState) {
is Loading -> { /* Loading Logic */ }
is Running -> { /* Running Logic */ }
else -> { /* .. */ }
}
}
위 처럼 Loading과 Running 상태일 때 상황에 맞는 동작을 처리하고 싶다면 when을 통해 처리할 수 있을 것이다. 하지만, 반드시 else 분기를 포함시켜야 한다. 그 이유는 위에서 설명한 것 처럼 컴파일러가 UiState를 상속하는 자식 클래스가 어떤 클래스인지 모르기 때문에 else를 통해 예외 상황에 대해 처리해줘야 하기 때문이다.
위 예시를 sealed class로 변경하게 되면 아래와 같다.
sealed class UiState
class Loading : UiState
class Running : UiState
fun doSomething(uiState: UiState): Any {
return when (uiState) {
is Loading -> { /* ... */ }
is Running -> { /* ... */ }
}
}
sealed class를 사용하게 되면 컴파일러가 UiState를 상속하는 하위 클래스가 Loading과 Running임을 알고 있기 때문에 else로 분기 처리를 하지 않아도 된다. Ui에 대한 다른 상태 클래스를 추가한다면 반드시 when에서 처리해야 할 것이다.
sealed class는 중첩 클래스(Nested Class)로도 정의할 수 있다.
sealed class UiState {
class Loading : UiState
class Running : UiState
}
val uiState: UiState = UiState.Loading
2. sealed class의 특징
sealed class는 아래와 같은 특징을 갖는다.
1. sealed class는 private 생성자만 갖는다.
2. sealed class와 이를 상속하는 서브 클래스는 반드시 동일한 패키지에서 정의되어야 한다.
3. 서브 클래스는 class, data class, object로 정의할 수 있다.
sealed clas의 서브 클래스로 일반 class를 사용할 경우 equals()를 override하라는 경고 메시지가 나온다. 만약, 상태 변수나 equals()를 override하지 않는 경우에는 메모리 측면에서 싱글톤한 특징을 갖는 object를 사용하는 것이 낫다.
sealed class UiState
class Loading(val a: Int) : UiState()
class Running : UiState() {
override fun equals(other: Any?): Boolean = super.equals(other)
}
3. enum class와의 차이점
sealed class와 마찬가지로 enum class도 서브 클래스들의 타입이 정해져있다. 하지만, enum class의 경우 서브로 존재하는 enum 상수들이 단일 인스턴스로만 존재하게 된다. 반면, sealed class는 인스턴스를 여러개 생성할 수 있다.
4. sealed class와 data class
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Double, val e2: Double) : Expr()
object NotANumber : Expr()
fun eval(expr: Expr): Double = when (expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
}
data class는 sealed class를 포함하여 다른 클래스로도 확장할 수 있다.
References
Sealed classes | Kotlin
kotlinlang.org
Sealed 클래스 · Kotlin 개인 정리
pluu.gitbooks.io
[Kotlin] Kotlin sealed class란 무엇인가?
sealed class의 등장 배경 여러 자식 Class들이 하나의 부모 Class를 상속 받았다고 했을 때 컴파일러는 부모 Class를 상속 받은 자식 Class들이 있는지 알지 못한다. 예를 들어보자. 우리가 사용자의 런닝
kotlinworld.com
Kotlin - Sealed class 구현 방법 및 예제
Sealed class는 Super class를 상속받는 Child 클래스의 종류 제한하는 특성을 갖고 있는 클래스입니다. Enum과의 차이점은 Enum은 single instance만 만들 수 있는 반면에 Sealed class는 여러개의 객체를 생성할
codechacha.com