Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A sealed class in Kotlin is an implicitly abstract class that restricts its inheritance hierarchy to a strictly defined, bounded set of subclasses. By defining a class as sealed, you guarantee to the compiler that all direct subclasses are known at compile time, preventing any external or arbitrary extension of the class hierarchy.
sealed class NetworkResponse {
    data class Success(val payload: String) : NetworkResponse()
    data class Failure(val code: Int, val exception: Throwable) : NetworkResponse()
    object InProgress : NetworkResponse()
}

Architectural Rules and Constraints

  • Implicitly Abstract: A sealed class cannot be instantiated directly. It behaves as an abstract class and can contain abstract members, properties, and implemented methods.
  • Constructor Visibility: The constructors of a sealed class are implicitly protected. You can explicitly declare them as private, but they can never be public.
  • Inheritance Scope (Kotlin 1.5+): All direct subclasses of a sealed class must be declared within the same package and the same compilation module as the sealed class itself. They cannot be extended by unknown classes in client code or third-party libraries.
  • Subclass Flexibility: Direct subclasses can be standard classes, data class declarations, singleton object declarations, or other sealed classes. Because a sealed class is a class, its subclasses cannot be interfaces.
  • Indirect Inheritance: The restriction applies only to direct subclasses. If a direct subclass is not marked as sealed or final (classes are final by default in Kotlin unless marked open), it can be extended by other classes anywhere in the codebase.

Exhaustive Type Checking

The primary mechanical advantage of a sealed class is its integration with Kotlin’s when expression. Because the compiler possesses a complete registry of all direct subclasses, it performs exhaustive type checking. If a when expression evaluates an instance of a sealed class and covers all possible subclass types, the compiler does not require an else branch.
fun evaluateResponse(response: NetworkResponse): String {
    return when (response) {
        is NetworkResponse.Success -> "Data: ${response.payload}"
        is NetworkResponse.Failure -> "Error: ${response.code}"
        NetworkResponse.InProgress -> "Loading..."
        // The compiler recognizes this is exhaustive. 
        // Adding an 'else' branch here is redundant and discouraged.
    }
}
If a new subclass is later added to the NetworkResponse sealed class, the compiler will immediately flag the when expression as an error until the new type is explicitly handled, ensuring structural safety across the codebase.
Master Kotlin with Deep Grasping Methodology!Learn More