Sealed는 봉인된이라는 뜻으로, 상속 가능한 자식 클래스를 제한하는데 사용한다.
모든 자식 클래스는 컴파일 타임에 미리 정의된다. 예측 가능한 계층 구조로 안정적인 코드를 작성할 수 있다.
자식 클래스가 미리 정해져야 하는 경우이다.
예시로 살펴보자.
abstract로 선언한 경우 컴파일러에서 인식하지 못하기 때문에, 선언한 클래스가 BlueCat, RedCat, GreenCat 세 개임에도 불구하고 else문을 따로 작성해줘야 한다.
val cat: Cat = BlueCat()
val result = when(cat) {
is BlueCat -> "blue"
is RedCat -> "red"
is GreenCat -> "green"
else -> "none"
}
abstract class Cat
class BlueCat: Cat()
class RedCat: Cat()
class GreenCat: Cat()
하지만 sealed로 선언한 경우 컴파일러가 자식 클래스를 인식하기 때문에, else를 작성하지 않아도 된다.
val cat: Cat = BlueCat()
val result = when(cat) {
is BlueCat -> "blue"
is RedCat -> "red"
is GreenCat -> "green"
}
seaeld class Cat
class BlueCat: Cat()
class RedCat: Cat()
class GreenCat: Cat()
상태 관리, 조건 분기 등에서 안전한 처리를 보장한다.
앱에서 데이터를 로드하는 동안, 여러 상태를 처리해야 한다.
// UI 상태를 정의하는 Sealed 클래스
sealed class UIState {
object Loading : UIState() // 로딩 중
data class Success(val data: String) : UIState() // 성공, 데이터 포함
data class Error(val exception: Throwable) : UIState() // 실패, 예외 포함
}
// UI 상태에 따라 화면을 업데이트하는 함수
fun updateUI(state: UIState) {
when (state) {
is UIState.Loading -> println("로딩 중...") // 로딩 중 UI 표시
is UIState.Success -> println("성공: ${state.data}") // 데이터를 화면에 표시
is UIState.Error -> println("에러 발생: ${state.exception.message}") // 에러 메시지 표시
}
}
외부에서 임의로 확장할 수 없도록 설계할 수 있다.
open class로 선언하여 확장이 가능한 경우, 예외가 발생할 수 있다.
// 일반적인 클래스를 사용
open class ApiResponse
// 클라이언트가 새로운 상태를 추가
class CustomResponse : ApiResponse()
sealed class를 사용하여 상속 가능한 자식 클래스를 제한할 수 있다.
// API 응답을 나타내는 sealed class
sealed class ApiResponse {
data class Success(val data: String) : ApiResponse()
data class Error(val message: String) : ApiResponse()
object Loading : ApiResponse()
}
// 라이브러리에서 응답을 처리하는 함수
fun handleResponse(response: ApiResponse) {
when (response) {
is ApiResponse.Success -> println("성공: ${response.data}")
is ApiResponse.Error -> println("에러: ${response.message}")
ApiResponse.Loading -> println("로딩 중...")
// else가 필요하지 않음: sealed class는 모든 상태가 컴파일 타임에 정의되므로
}
}
sealed class로 선언했을 경우, 클라이언트에서 새로운 상태를 정의하려고 하면 컴파일 에러가 발생한다.
// 컴파일 에러 발생: ApiResponse는 sealed class이므로 외부에서 상속 불가
class CustomResponse : ApiResponse()
// 에러 처리 클래스
sealed class ErrorType {
data class NetworkError(val code: Int) : ErrorType()
data class ServerError(val message: String) : ErrorType()
object UnknownError : ErrorType()
}
// 인증 상태 관리
sealed class AuthState {
object LoggedIn : AuthState()
object LoggedOut : AuthState()
data class Error(val reason: String) : AuthState()
}