질문 이력:
sealed 수정자가 있는 인터페이스는 sealed class 개념의 발전으로 코틀린에 등장했습니다. 코틀린 1.5 버전까지 sealed 클래스만이 가능한 상속자의 세트를 제한할 수 있었으며, 이는 상태 머신, DSL 등에서 안전하게 작업하는 데 특히 중요합니다. sealed 인터페이스를 도입함으로써 개발자는 클래스에 구애받지 않고 인터페이스의 구현을 유사하게 제한할 수 있는 기능을 제공했습니다.
문제:
단순한 열린 인터페이스는 프로그램 어디서나 구현될 수 있으며, 이는 구현 수의 통제할 수 없는 증가와 코드 유지 보수의 복잡성을 초래할 수 있습니다. when 표현식으로 처리할 때, 컴파일러는 고려되지 않은 분기가 있을 경우 경고를 할 수 없습니다.
해결책:
Sealed interface는 동일한 모듈(또는 인터페이스가 top-level이 아닐 경우 동일한 파일) 내에서 정의된 구현만 허용합니다. 이는 안전한 enum-like 구조, ADT 패턴 및 상태 처리기에 대한 제어 방법으로 적용됩니다. 컴파일러는 모든 구현을 알고 있으며 코드 분석에 도움을 줍니다.
코드 예시:
sealed interface NetworkResult class Success(val data: String): NetworkResult class Error(val cause: Throwable): NetworkResult object Loading: NetworkResult fun handleResult(result: NetworkResult): String = when (result) { is Success -> "Success with ${result.data}" is Error -> "Error: ${result.cause.message}" Loading -> "Loading..." }
주요 특징:
현재 파일 외부에서 sealed 인터페이스를 구현할 수 있나요?
답변: sealed 클래스와 달리 sealed 인터페이스는 다른 파일에서 구현할 수 있지만, 현재 모듈(또는 인터페이스가 top-level이 아닐 경우 컴파일 단위) 내에서만 가능합니다.
sealed 인터페이스가 기본 구현이 있는 공개 메서드를 가질 수 있나요?
예, 일반 인터페이스와 마찬가지로 sealed 인터페이스는 기본 함수 구현을 포함할 수 있습니다.
sealed interface Mode { fun description(): String = "Unknown mode" }
표준 직렬 변환기(예: kotlinx.serialization)를 사용하여 sealed 인터페이스를 직렬화할 수 있나요?
가능하지만 모든 구현을 명시적으로 지정해야 합니다. Kotlinx.serialization에서 sealed 인터페이스에 대한 지원이 즉시 제공되지 않았으며, 직렬화 가능한 유형을 명시적으로 지정하는 것이 중요합니다.
프로젝트에서 모든 UI 상태 유형에 대해 sealed 인터페이스를 설명했지만, 구현이 애플리케이션의 여러 부분에서 나타나기 시작했습니다. 그런 다음 새로운 상태 유형을 추가했지만 처리 블록을 업데이트하는 것을 잊어, 로그에서 새로운 상태가 무시되는 결과를 초래했습니다.
장점:
단점:
모든 네트워크 응답에 대해 sealed 인터페이스를 사용했습니다. 새로운 응답 유형을 추가할 때 IDE가 자동으로 when을 통해 처리되는 모든 지점을 강조 표시했습니다. 오류가 즉시 수정되어 로직에서 예상치 못한 구멍이 발생하지 않았습니다.
장점:
단점: