Question #376MediumNative Android

What are sealed classes and when would you use them in Kotlin/Java?

#kotlin#sealed-classes#type-safety

Answer

Overview

Sealed classes represent restricted class hierarchies with a fixed set of subclasses.


Syntax

kotlin
sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

Exhaustive when

kotlin
fun handleResult(result: Result<User>) {
    when (result) {
        is Result.Success -> println(result.data)
        is Result.Error -> println(result.message)
        is Result.Loading -> println("Loading...")
        // No else needed - compiler knows all cases
    }
}

Use Cases

1. State Management

kotlin
sealed class UiState {
    object Idle : UiState()
    object Loading : UiState()
    data class Success(val data: List<Item>) : UiState()
    data class Error(val error: String) : UiState()
}

2. API Responses

kotlin
sealed class ApiResponse<out T> {
    data class Success<T>(val data: T) : ApiResponse<T>()
    data class HttpError(val code: Int) : ApiResponse<Nothing>()
    data class NetworkError(val ex: Exception) : ApiResponse<Nothing>()
}

Sealed vs Enum

Enum Limitations

kotlin
enum class Status { SUCCESS, ERROR, LOADING }
// Cannot hold different data types

Sealed Classes

kotlin
sealed class Status {
    data class Success(val data: String) : Status()
    data class Error(val exception: Exception) : Status()
    object Loading : Status()
}

Java Alternative

java
// Java 17+ sealed classes
public sealed interface Result 
    permits Success, Error, Loading {
    
    record Success(String data) implements Result {}
    record Error(String message) implements Result {}
    final class Loading implements Result {}
}

Best Practice: Use sealed classes for type-safe state machines and API responses.