Kotlin의 초기 버전에서 타입 계층을 제한하기 위해 sealed 클래스가 사용되었으며, 이를 통해 개발자는 하위 타입을 명시적으로 제어할 수 있었습니다. 하지만 인터페이스를 사용하여 유사한 계층을 설명해야 할 경우에는 이 방법이 충분하지 않았습니다. 이를 해결하기 위해 Kotlin 1.5부터 인터페이스를 위한 sealed 수정자가 도입되었습니다.
일반 인터페이스는 프로젝트의 아무 곳에서나 구현할 수 있도록 허용하므로, 종종 타입 계층의 절대적 폐쇄성을 보장하는 데 방해가 될 수 있으며, 포괄적인 타입 검사(exhaustive when)를 사용하는 것을 방해할 수 있습니다. 이는 런타임에서 오류가 발생하거나 모든 경우를 정적으로 확인하는 것이 불가능할 수 있습니다.
Sealed 인터페이스는 하나의 파일 내에서 구현 클래스 목록을 제한할 수 있어 타입 시스템의 예측 가능성을 높이고 패턴 매칭에서의 안전성을 강화합니다.
sealed interface NetworkResult class Success(val data: String): NetworkResult class Failure(val error: Throwable): NetworkResult fun handle(result: NetworkResult) = when(result) { is Success -> println("Data: ${result.data}") is Failure -> println("Error: ${result.error}") // 모든 경우가 고려되었으므로 'else'는 필요 없음 }
주요 특징:
sealed interface를 별도의 파일에 추가하거나 원래 파일 밖에서 구현할 수 있나요?
아니요. sealed interface를 직접 구현하는 모든 타입은 동일한 파일 내에서 선언되어야 합니다. 그렇지 않으면 컴파일러가 오류를 발생시킵니다.
sealed 인터페이스가 선언 파일 밖에 서브인터페이스를 가질 수 있나요?
아니요. 서브인터페이스도 동일한 파일 내에 있어야 합니다. 모든 계층은 파일 안에 폐쇄되어 있습니다.
sealed 인터페이스가 런타임 성능에 영향을 미치나요?
직접적으로는 아니지만, 컴파일 단계에서 안전한 타입 검사를 사용할 수 있게 하여 런타임 오류의 발생 가능성을 줄이고, 코드를 단순화하며, 간접적으로 테스트 속도를 높일 수 있습니다.
개발자가 하나의 파일에 sealed 인터페이스 NetworkAction을 선언하지만, 구현체가 여러 클래스와 파일에 분산되어 있습니다. 나중에 문제가 발생하여 컴파일러가 규칙 위반을 알리며 구조를 수정하기 어려워집니다, 특히 큰 프로젝트에서.
장점:
단점:
Sealed 인터페이스 OrderResult와 클래스 Success/Failure가 하나의 파일 내에서 선언됩니다. when 검사는 항상 포괄적이며, 어떤 분기도 пропущ되지 않습니다.
장점:
단점: