sealed class
는 부모 클래스를 상속받는 자식 클래스의 종류를 제한하는 특성을 갖고 있는 클래스이다.
어떠한 클래스를 상속받는 하위 클래스는 여러 파일에 존재할 수 있기 때문에 컴파일러는 얼마나 많은 하위 클래스들이 있는지 알지 못한다.
하지만 sealed class
는 동일 파일에 정의된 하위 클래스 외에 다른 하위 클리스는 존재하지 않는다는 것을 컴파일러에게 알려주는 것과 같다.
즉, 컴파일러가 sealed class의 자식 클래스가 어떤 것이 있는지 알 수 있다.
예를 들어 State
상위 클래스를 만들고, 동일한 파일에 이 클래스를 상속하는 Loading
, Success
, Error
클래스를 선언하고 getMessage 메서드를 추가해보자.
abstract class AppState
object Loading: State()
object Success: State()
object Error: State()
fun getMessage(appState: AppState): String {
return when(appState) {
is Loading -> "Loading"
is Success -> "Success"
is Error -> "Error"
}
}
하지만 이렇게 작성하면 'else' branch
를 추가하라는 오류가 발생한다. else
를 추가해야 하는 이유는 무엇일까?
컴파일러가 State 클래스
를 상속받는 하위 클래스의 종류를 알지 못해서이다.
어떠한 클래스를 상속받는 하위 클래스는 여러 파일에 존재할 수 있기 때문에 컴파일러는 얼마나 많은 하위 클래스들이 있는지 알지 못하기 때문이다.
따라서 아래의 코드처럼 else
구문을 추가해줘야 오류가 발생하지 않는다.
return when(appState) {
is Loading -> "Loading!!"
is Success -> "Success!!"
is Error -> "Error"
else -> "No State"
}
만약 클래스를 추가해 확장하고 싶어 UnInitialized 클래스
를 추가한다고 가정해보자.
abstract class AppState
object UnInitialized: State()
object Loading: State()
object Success: State()
object Error: State()
fun getMessage(appState: AppState): String {
return when(appState) {
is Loading -> "Loading"
is Success -> "Success"
is Error -> "Error"
else -> "No State"
}
}
하지만 실수로 UnInitialized에 대한 코드를 추가하지 않았다면? 그래도 else
구문이 있기 때문에 컴파일이 잘 된다.
자 그러면 이제 sealed class로 구현해보자.
sealed class AppState
object Loading: State()
object Success: State()
object Error: State()
fun getMessage(appState: AppState): String {
return when(appState) {
is Loading -> "Loading"
is Success -> "Success"
is Error -> "Error"
}
}
sealed class로 구현 시, else
없이도 컴파일이 잘 된다. 컴파일러는 State 상위 클래스
의 하위클래스에는 Loading 클래스
, Success 클래스
, Error 클래스
만 있다고 생각하기 때문이다. 즉, 모든 케이스에 대해 처리하고 있기 때문에 else
없어도 컴파일이 잘 되는 것이다.
만약 클래스를 추가해 확장하고 싶어 UnInitialized
클래스를 추가한다고 가정해보자.
sealed class AppState
object UnInitialized: State()
object Loading: State()
object Success: State()
object Error: State()
하지만 실수로 UnInitialized에 대한 코드를 추가하지 않았다고 가정해보자.
fun getMessage(appState: AppState): String {
return when(appState) {
is Loading -> "Loading"
is Success -> "Success"
is Error -> "Error"
}
}
이러면 else
가 없기 때문에 컴파일 에러가 발생한다.
아래과 같이 UnInitialized에 대한 코드를 추가해줘야 컴파일 에러가 발생하지 않는다.
return when(appState) {
is Loading -> "Loading"
is Success -> "Success"
is Error -> "Error"
is UnInitialized -> "UnInitialized"
}
sealed class 특징
class
, data class
, object class
로 정의할 수 있다.참고