[Kotlin] sealed class

jeunguri·2022년 5월 9일
0

kotlin

목록 보기
1/5


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 특징

  • abstract 클래스로 객체를 생성할 수 없다.
  • sealed class의 생성자는 private이다.
  • sealed class와 그 하위 클래스는 동일한 파일에 정의되어야 한다. 서로 다른 파일에서 정의할 수 없다.
  • 하위 클래스는 class, data class, object class로 정의할 수 있다.


참고

0개의 댓글