Skip to Content

Sealed Class trong Kotlin

1. Giới thiệu

Sealed class giới hạn các subclasses có thể có, hữu ích cho representing restricted hierarchies.

2. Khai báo Sealed Class

sealed class Result { data class Success(val data: String) : Result() data class Error(val message: String) : Result() object Loading : Result() } fun handleResult(result: Result) { when (result) { is Result.Success -> println("Data: ${result.data}") is Result.Error -> println("Error: ${result.message}") Result.Loading -> println("Loading...") } }

3. when Exhaustive

sealed class Color { object Red : Color() object Green : Color() object Blue : Color() } fun getColorCode(color: Color): String { // Không cần else vì đã cover hết return when (color) { Color.Red -> "#FF0000" Color.Green -> "#00FF00" Color.Blue -> "#0000FF" } }

4. Sealed với Data Class

sealed class ApiResponse<out T> { data class Success<T>(val data: T) : ApiResponse<T>() data class Error(val code: Int, val message: String) : ApiResponse<Nothing>() object Loading : ApiResponse<Nothing>() } fun <T> handleResponse(response: ApiResponse<T>) { when (response) { is ApiResponse.Success -> println("Got: ${response.data}") is ApiResponse.Error -> println("Error ${response.code}: ${response.message}") ApiResponse.Loading -> println("Loading...") } }

5. Nested Sealed Classes

sealed class UIState { object Idle : UIState() object Loading : UIState() sealed class Loaded : UIState() { data class Success(val data: List<String>) : Loaded() data class Empty(val message: String) : Loaded() } data class Error(val exception: Throwable) : UIState() }

6. Sealed Interface (Kotlin 1.5+)

sealed interface Error class IOError(val message: String) : Error class NetworkError(val code: Int) : Error object UnknownError : Error fun handle(error: Error) = when (error) { is IOError -> println("IO: ${error.message}") is NetworkError -> println("Network: ${error.code}") UnknownError -> println("Unknown error") }

7. State Machine với Sealed Class

sealed class PlayerState { object Idle : PlayerState() data class Playing(val position: Int) : PlayerState() data class Paused(val position: Int) : PlayerState() object Stopped : PlayerState() } class MusicPlayer { var state: PlayerState = PlayerState.Idle fun play() { state = when (val current = state) { PlayerState.Idle -> PlayerState.Playing(0) is PlayerState.Paused -> PlayerState.Playing(current.position) else -> state } } }

8. So sánh với Enum

// Enum - mỗi instance giống nhau enum class Color { RED, GREEN, BLUE } // Sealed class - mỗi subclass có structure khác nhau sealed class Shape { data class Circle(val radius: Double) : Shape() data class Rectangle(val w: Double, val h: Double) : Shape() }

9. Ví dụ thực tế: Network Response

sealed class NetworkResult<out T> { data class Success<T>(val data: T) : NetworkResult<T>() data class HttpError(val code: Int, val body: String?) : NetworkResult<Nothing>() data class NetworkError(val exception: Exception) : NetworkResult<Nothing>() } suspend fun fetchUser(): NetworkResult<User> { return try { val response = api.getUser() if (response.isSuccessful) { NetworkResult.Success(response.body()!!) } else { NetworkResult.HttpError(response.code(), response.errorBody()?.string()) } } catch (e: Exception) { NetworkResult.NetworkError(e) } }

📝 Tóm tắt

  • sealed class giới hạn subclasses
  • Tất cả subclasses định nghĩa trong cùng file
  • when exhaustive - không cần else
  • Kết hợp với data class cho rich data
  • Phù hợp cho state machines, error handling
  • Sealed interface từ Kotlin 1.5+
Last updated on