Hanbit the Developer

Kotlin Documentation | Sealed classes and interfaces 본문

Mobile/Kotlin

Kotlin Documentation | Sealed classes and interfaces

hanbikan 2023. 5. 23. 13:14

Kotlin Documentation 시리즈에 대해

Category: Concepts - Classes and objects

문서 링크: https://kotlinlang.org/docs/sealed-classes.html


sealed 클래스의 서브클래스는 컴파일 타임에 알려져있으며, sealed class가 정의된 곳이 아닌, 다른 모듈이나 다른 패키지에서 또다른 서브클래스가 정의될 수 없다.

sealed interface는 다른 모듈에서만 재정의가 불가능하다.(모듈이 컴파일되면 새 구현체가 나타날 수 없다.)

 

enum 또한 값들의 집합이 제한되어 있다는 점이 있어 유사하다. 하지만 enum의 상수는 single instance로서 존재하는 반면, sealed class의 서브클래스는 여러 인스턴스를 가질 수 있다.

sealed interface Error

sealed class IOError(): Error

class FileReadError(val file: File): IOError()
class DatabaseError(val source: DataSource): IOError()

object RuntimeError : Error

sealed class는 abstract class이며, 직접 인스턴스화할 수 없으며(위 예시에서 Error(), IOError()로 인스턴스를 생성하는 것이 불가능하다는 의미임) abstract member를 가질 수 있다:

sealed interface SearchUiState {
    val abstract: Int
    
    object Loading: SearchUiState {
        override val abstract: Int = 1
    }
}
sealed class SearchUiState {
    abstract val abstract: Int

    object Loading: SearchUiState() {
        override val abstract: Int = 1
    }
}

sealed class의 생성자는 visibility modifier로 protected(by default), private를 가질 수 있다.

Location of direct subclasses

sealed class의 direct subclass는 같은 패키지에 정의되어야 하며 가능한 모든 visibility modifier를 가질 수 있다. local 또는 anonymous object가 될 수 없다.

이러한 제약 사항은 indirect subclass에는 적용되지 않는다. direct subclass가 sealed가 아니라면 이를 확장할 수 있다.

Inheritance in multiplatform projects

멀티 플랫폼에서는 direct subclass가 same source set에 있어야 한다. 이는 expect, actual 키워드가 없는 sealed class에 적용된다.

Sealed classes and when expression

fun log(e: Error) = when(e) {
    is FileReadError -> { println("Error while reading file ${e.file}") }
    is DatabaseError -> { println("Error while reading from database ${e.source}") }
    is RuntimeError ->  { println("Runtime error") }
    // the `else` clause is not required because all the cases are covered
}