Sealed 클래스 - swkim0128/PARA GitHub Wiki
코틀린의 **Sealed 클래스(봉인 클래스)**는 상속이 가능한 클래스이지만, 상속할 수 있는 하위 클래스를 제한하는 기능을 가진 클래스입니다.
이는 enum class와 abstract class의 장점을 결합한 형태로, 계층 구조를 갖는 데이터 모델을 정의할 때 유용합니다.
- sealed 키워드를 사용하여 선언.
- 같은 파일 내에서만 하위 클래스를 정의할 수 있음.
- when 표현식에서 모든 경우를 처리했는지 컴파일러가 검사해줌.
기본 문법
sealed class 클래스이름 {
class 하위클래스1 : 클래스이름()
class 하위클래스2 : 클래스이름()
}
sealed class Shape {
class Circle(val radius: Double) : Shape()
class Rectangle(val width: Double, val height: Double) : Shape()
}
fun describe(shape: Shape): String {
return when (shape) {
is Shape.Circle -> "원의 반지름: ${shape.radius}"
is Shape.Rectangle -> "사각형의 크기: ${shape.width} x ${shape.height}"
}
}
fun main() {
val circle = Shape.Circle(5.0)
val rectangle = Shape.Rectangle(4.0, 6.0)
println(describe(circle)) // 출력: 원의 반지름: 5.0
println(describe(rectangle)) // 출력: 사각형의 크기: 4.0 x 6.0
}
✅ Sealed 클래스는 when과 함께 사용하면 else 없이 모든 경우를 반드시 처리해야 함. ✅ 각 하위 클래스는 Shape을 상속받아 다른 동작을 정의할 수 있음.
구분 | Sealed 클래스 | Enum 클래스 |
---|---|---|
상속 여부 | 하위 클래스 상속 가능 | 불가능 |
데이터 포함 | 여러 개의 프로퍼티 포함 가능 | 단일 인스턴스만 가능 |
인스턴스 생성 | 하위 클래스의 인스턴스 생성 가능 | Enum 상수만 사용 가능 |
확장성 | 새로운 서브클래스를 추가할 수 있음 | Enum 값 추가 가능하지만 제한적 |
차이점 예제
enum class Color {
RED, GREEN, BLUE
}
sealed class Shape {
class Circle(val radius: Double) : Shape()
}
✅ enum class는 단순한 값의 열거형 ✅ sealed class는 데이터와 동작을 포함하는 계층 구조 모델링 가능
object를 사용하면 싱글톤 형태의 하위 클래스를 만들 수 있음.
예제
sealed class NetworkState {
object Loading : NetworkState()
object Success : NetworkState()
data class Error(val message: String) : NetworkState()
}
fun handleState(state: NetworkState) {
when (state) {
is NetworkState.Loading -> println("로딩 중...")
is NetworkState.Success -> println("성공!")
is NetworkState.Error -> println("오류 발생: ${state.message}")
}
}
fun main() {
handleState(NetworkState.Loading) // 출력: 로딩 중...
handleState(NetworkState.Success) // 출력: 성공!
handleState(NetworkState.Error("네트워크 연결 실패")) // 출력: 오류 발생: 네트워크 연결 실패
}
✅ object를 사용하면 인스턴스를 생성할 필요 없이 싱글톤처럼 사용할 수 있음. ✅ 하위 클래스 중 Error만 data class로 정의하여 추가적인 데이터를 포함하도록 구현.
- 코틀린 1.5부터 인터페이스에도 sealed 적용 가능.
- sealed interface는 다른 파일에서도 구현 가능(클래스와 차이점).
예제
sealed interface Animal
class Dog : Animal
class Cat : Animal
✅ Sealed 인터페이스는 여러 파일에서 구현 가능하지만, Sealed 클래스는 같은 파일에서만 가능!
sealed class ApiResponse<out T> {
object Loading : ApiResponse<Nothing>()
data class Success<T>(val data: T) : ApiResponse<T>()
data class Error(val errorMessage: String) : ApiResponse<Nothing>()
}
fun handleResponse(response: ApiResponse<String>) {
when (response) {
is ApiResponse.Loading -> println("로딩 중...")
is ApiResponse.Success -> println("데이터: ${response.data}")
is ApiResponse.Error -> println("오류 발생: ${response.errorMessage}")
}
}
fun main() {
handleResponse(ApiResponse.Loading) // 출력: 로딩 중...
handleResponse(ApiResponse.Success("API 데이터")) // 출력: 데이터: API 데이터
handleResponse(ApiResponse.Error("서버 오류")) // 출력: 오류 발생: 서버 오류
}
✅ 서버 응답을 Loading, Success, Error 상태로 관리 가능 ✅ when을 사용하면 모든 상태를 처리할 수 있음
sealed class UserAction {
object Click : UserAction()
object LongPress : UserAction()
data class Swipe(val direction: String) : UserAction()
}
fun handleAction(action: UserAction) {
when (action) {
is UserAction.Click -> println("클릭")
is UserAction.LongPress -> println("길게 누름")
is UserAction.Swipe -> println("스와이프 방향: ${action.direction}")
}
}
fun main() {
handleAction(UserAction.Click) // 출력: 클릭
handleAction(UserAction.Swipe("오른쪽")) // 출력: 스와이프 방향: 오른쪽
}
✅ 사용자 액션을 Click, LongPress, Swipe 등으로 정의 가능 ✅ 각 이벤트를 when을 통해 처리할 수 있어 가독성 높아짐
기능 | 설명 | 예제 |
---|---|---|
정의 | 특정 클래스의 하위 클래스를 제한 | sealed class Shape |
파일 제한 | 같은 파일 내에서만 하위 클래스 정의 가능 | sealed class Status { class Success : Status() } |
when 사용 | when에서 else 없이 모든 경우 처리 가능 | when(status) { is Success -> ... } |
싱글톤 형태 | object를 사용하여 하나의 인스턴스만 유지 | object Loading : State() |
데이터 포함 | data class를 사용하여 데이터 전달 가능 | data class Error(val msg: String) : State() |
Sealed 인터페이스 | 코틀린 1.5부터 지원 (다른 파일에서도 구현 가능) | sealed interface Animal { class Dog : Animal } |
✅ Sealed 클래스는 enum class보다 더 유연한 계층 구조를 가질 수 있음. ✅ 서브클래스를 제한하여 안전한 타입 설계를 가능하게 함. ✅ when과 함께 사용하면 모든 상태를 명확하게 정의할 수 있음. ✅ 네트워크 응답 처리, 상태 관리, 사용자 입력 이벤트 처리 등 다양한 상황에서 유용하게 활용 가능.
💡 Sealed 클래스를 활용하면 코드의 가독성을 높이고, 타입 안정성을 확보할 수 있습니다! 🚀