Kotlin sealed classes are a powerful feature that allows you to define a restricted class hierarchy. Unlike regular classes, sealed classes can only be subclassed within the same file. This makes them particularly useful for representing a fixed set of types, which can be helpful in scenarios like state management or handling various data responses. Below are three practical examples of Kotlin sealed classes to illustrate their usage in real-world applications.
When dealing with network operations, it’s common to have multiple states for the response, such as success, error, or loading. Using sealed classes allows for a clearer representation of these states.
sealed class NetworkResponse<out T> {
data class Success<out T>(val data: T) : NetworkResponse<T>()
data class Error(val exception: Exception) : NetworkResponse<Nothing>()
object Loading : NetworkResponse<Nothing>()
}
fun handleResponse(response: NetworkResponse<String>) {
when (response) {
is NetworkResponse.Success -> println("Data received: \
${response.data}")
is NetworkResponse.Error -> println("Error occurred: \
${response.exception.message}")
NetworkResponse.Loading -> println("Loading...")
}
}
Using sealed classes helps ensure that all possible states are handled in the when
expression, preventing any unhandled cases that could lead to runtime errors.
In a typical Android application, the UI can be in multiple states such as idle, loading, or displaying data. Sealed classes can effectively model these UI states.
sealed class UiState {
object Idle : UiState()
object Loading : UiState()
data class Success(val data: List<String>) : UiState()
data class Error(val message: String) : UiState()
}
fun updateUiState(state: UiState) {
when (state) {
is UiState.Idle -> showIdleView()
is UiState.Loading -> showLoadingView()
is UiState.Success -> showData(state.data)
is UiState.Error -> showError(state.message)
}
}
Using sealed classes for UI states makes the codebase cleaner and easier to maintain, as it gives a clear structure to the different states the UI can be in.
In applications that require user authentication, there are various states such as logged in, logged out, or error. Sealed classes can encapsulate these states clearly.
sealed class AuthState {
object LoggedIn : AuthState()
object LoggedOut : AuthState()
data class Error(val message: String) : AuthState()
}
fun handleAuthState(state: AuthState) {
when (state) {
AuthState.LoggedIn -> navigateToHome()
AuthState.LoggedOut -> navigateToLogin()
is AuthState.Error -> showError(state.message)
}
}
This approach centralizes the handling of authentication states, making it easier to expand or modify in the future without affecting other parts of the application.