Kotlin의 sealed class는 자식 클래스의 계층을 제한하는 추상 클래스입니다: 모든 하위 유형은 하나의 파일에서 선언되어야 합니다. 이는 선택 사항 집합이 고정된 계층에 유용합니다(예: 상태, 이벤트 또는 오류 설명):
sealed class Result { object Success : Result() data class Error(val message: String) : Result() object Loading : Result() } fun handle(result: Result) = when (result) { is Result.Success -> print("Success!") is Result.Error -> println("Error: ${result.message}") is Result.Loading -> println("Loading...") }
when과의 관계:
모든 sealed class의 하위 유형을 when 표현식에서 사용하면, 컴파일러는 exhaustiveness(모든 경우의 수를 처리하는 것)를 검사합니다. 이는 새로운 상태를 추가할 때, 개발자가 새로운 경우를 처리하지 않으면 컴파일 오류를 발생시킴을 보장합니다.
이유:
"sealed class의 상속자를 다른 파일이나 패키지에 배치할 수 있는가? 이것이 type-safety에 어떤 영향을 미치는가?"
답변: 아니요, 모든 sealed class의 직접 상속자는 동일한 파일 내에 정의되어야 합니다. 이는 type-safety 보장을 위한 컴파일러의 제어입니다. 상속자를 다른 패키지의 파일에 배치하면 컴파일러가 오류를 발생시킵니다.
이야기
결제 비즈니스 로직을 설계할 때, 결과 작업 옵션을 추가했지만 when 표현식을 업데이트하는 것을 잊었습니다. 하지만 sealed class 덕분에 컴파일러가 누락된 경우를 강조했습니다. Java의 다른 프로젝트에서는 이 시나리오가 초기화되지 않은 상태가 제품에 포함되는 결과를 초래했을 것입니다.
이야기
프로젝트에서 일부 데이터를 sealed class에서 일반 open class로 마이그레이션한 후 exhaustive when 검사가 작동하지 않게 되어, 새로운 상태가 처리 논리에서 "사라지는" 일이 발생하여 인터페이스에서 잘못된 동작이 일어났습니다.
이야기
전자 상거래 시스템에서 재사용을 위해 sealed class의 상속자를 별도의 파일로 분리하는 아키텍처 최적화를 시도했습니다. 이는 컴파일을 깨뜨리고 릴리스 전에 긴급 리팩토링의 원인이 되었습니다.