Phase 3 · Object-Oriented KotlinModule 18~36 min read

Sealed Classes & Enums

Model restricted hierarchies and states with enums and sealed classes — perfect with when.

What you'll learn

Enums and sealed classes both model "one of a fixed set of possibilities" — but at different levels. Together with when, they let you model states and results in a way the compiler checks for completeness. This is one of Kotlin's real superpowers.

By the end you'll be able to:

  • Define enum classes, including ones with properties and methods
  • Model restricted hierarchies with sealed classes
  • Write exhaustive when expressions the compiler verifies
  • Know when to reach for an enum vs a sealed class

Enum classes

An enum class defines a fixed set of named constants — days of the week, directions, states. It gives you type safety (only valid values compile) and useful built-ins like ordinal and entries:

Direction.kt
enum class Direction {
    NORTH, SOUTH, EAST, WEST
}

val d = Direction.NORTH
println(d)                       // NORTH
println(d.ordinal)               // 0 (its position)
println(Direction.entries.size)  // 4 (all values)

Enums with data & methods

Kotlin enums are more than labels — each constant can carry data and the enum can have methods. This makes them ideal for lookup tables with behaviour attached:

Planet.kt
enum class Planet(val gravity: Double) {
    EARTH(9.81),
    MARS(3.71),
    MOON(1.62);                   // note the semicolon before members

    fun weightOf(mass: Double) = mass * gravity
}

println(Planet.MARS.gravity)         // 3.71
println(Planet.EARTH.weightOf(10.0)) // 98.1

Sealed classes

An enum's values are all identical in shape. But often you need a fixed set of possibilities where each carries different data — a Success holds a result, an Error holds a message. That's a sealed class: a restricted hierarchy where all subclasses are known to the compiler:

enum vs sealed

enum

A fixed set of single instances (constants). Each value is the same shape.

Direction.NORTH, SOUTH…

sealed

A fixed set of subtypes, each able to hold its own data. Perfect for results and state.

Success(data), Error(msg), Loading

The payoff: exhaustive when

Because the compiler knows every subclass of a sealed class, a when over one can be checked for exhaustiveness — no else branch needed. And if you add a new subtype later, the compiler forces you to handle it everywhere. A whole class of bugs, gone:

Result.kt
sealed class Result
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
object Loading : Result()

fun handle(result: Result) = when (result) {   // no 'else' needed — exhaustive!
    is Success -> "Got: ${result.data}"
    is Error -> "Failed: ${result.message}"
    Loading -> "Loading..."
}

println(handle(Success("Hello")))
println(handle(Error("Oops")))
println(handle(Loading))

Key idea

This Result pattern — Success/Error/Loading as a sealed hierarchy — is everywhere in real Kotlin, especially Android. It models an operation's state safely, and the exhaustive when guarantees you never forget to handle a case.

Recap & quick check

Key takeaways

  • An enum class is a fixed set of named constants; each value can carry data and the enum can have methods.
  • A sealed class is a fixed set of subtypes, each able to hold its own different data.
  • The compiler knows all subclasses of a sealed class, so a when over it can be exhaustive (no else).
  • Add a new sealed subtype and the compiler forces you to handle it in every when — safety at scale.
  • Use enums for identical constants; sealed classes for a closed set of differently-shaped cases (results, state).

Quick check

1. What is an enum class?

2. What can Kotlin enum constants carry?

3. What's the key benefit of a sealed class with 'when'?

4. When should you use a sealed class instead of an enum?

5. If you add a new subtype to a sealed class, what happens to existing exhaustive 'when' blocks?

Excellent — you can model states and results safely now. Next up: Module 19 — Visibility, Nested & Inner Classes, the finale of Phase 3.