Sealed Classes & Enums
Kotlin is a modern, concise language that lets you model a fixed set of possibilities precisely — enums for constant values and sealed classes for restricted hierarchies where each case carries its own data.
Learn Sealed Classes & Enums in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll define enums with data and methods, build sealed class hierarchies, and handle them exhaustively with when .
What You'll Learn in This Lesson
1️⃣ Enums
An enum class defines a fixed set of named constants. Each constant can carry data (passed to a constructor), and the enum can have shared properties and methods. You can iterate all values and use name and ordinal .
Because an enum's cases are fixed, a when over it is exhaustive — the compiler knows you covered every direction, so no else is needed.
2️⃣ Sealed Classes
A sealed class has a closed set of subclasses, all known to the compiler. Unlike an enum, each case can carry different data — making sealed classes ideal for modelling outcomes like success, error, and loading.
The when in handle needs no else , and each is branch smart-casts the result so you can read its specific data directly.
Your turn. Replace the TODO , then run and compare.
Mini-Challenge: A Payment Outcome
Model three different outcomes with a sealed class and handle them exhaustively.
Common Errors (and the fix)
- "'when' must be exhaustive" — You missed a case. Add the remaining branches (or an else if you can't cover all).
- Forgetting the ; after enum constants — When an enum also has methods, a semicolon separates the constants from the members.
- Calling a constructor on an object case — A singleton case like Loading takes no () ; reference it directly.
- Subclass outside the sealed file — Sealed subclasses must be in the same file/module so the compiler can see them all.
Pro Tips
- 💡 Assign the when result — when used as an expression, the compiler enforces exhaustiveness for you.
- 💡 Sealed for state machines: they shine for UI states (Loading/Success/Error) and parser results.
- 💡 entries over values(): newer Kotlin offers EnumName.entries as a modern alternative to values() .
📋 Quick Reference — Sealed & Enums
Concept
Kotlin Syntax
Enum
enum class Dir { NORTH, SOUTH }
Enum with data
EARTH(9.8)
All values
Dir.values()
Sealed class
sealed class Result
Data case
data class Ok(...) : Result()
Singleton case
object Loading : Result()
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ Enums are a fixed set of named constants, optionally with data and methods
- ✅ Sealed classes are restricted hierarchies whose cases carry different data
- ✅ object cases are singletons with no data
- ✅ when over enums/sealed is exhaustive — no else
- ✅ is branches smart-cast to the specific case
- ✅ Next lesson: Generics
Practice quiz
What is an enum class?
- A class with no methods
- A class that cannot be instantiated
- A fixed set of named constants
- A type alias
Answer: A fixed set of named constants. An enum class defines a fixed set of named constants.
What does the ordinal property of an enum constant give you?
- Its zero-based position in the declaration order
- Its name as text
- A random id
- Its constructor argument
Answer: Its zero-based position in the declaration order. ordinal is the zero-based position; the first constant has ordinal 0.
When is a when over an enum exhaustive without an else?
- Never, an else is always required
- Only with more than three constants
- Only when used as a statement
- When it covers every constant of the enum
Answer: When it covers every constant of the enum. The compiler knows all constants, so covering them all makes when exhaustive.
How does a sealed class differ from an enum?
- It cannot be used in when
- Its cases can each carry different data
- It has no subclasses
- It is always a singleton
Answer: Its cases can each carry different data. Sealed-class cases can each carry different data, unlike enum constants.
Why does object Loading : Result() use object instead of a data class?
- Loading carries no data, so a single shared instance fits
- Loading needs many instances
- data classes cannot extend sealed classes
- object is faster to type
Answer: Loading carries no data, so a single shared instance fits. A no-data case is best modeled as an object singleton.
In when, what does an is Result.Success branch let you do with the value?
- Nothing extra
- Only print it
- Smart-cast it to Success and read its data directly
- Cast it manually with as
Answer: Smart-cast it to Success and read its data directly. An is branch smart-casts the value to the specific subtype.
Where must a sealed class's subclasses be declared?
- Anywhere in the project
- In the same file or module so the compiler sees them all
- Only inside a companion object
- In a separate library
Answer: In the same file or module so the compiler sees them all. Sealed subclasses must be in the same file/module for exhaustiveness checking.
Can an enum constant carry constructor data?
- No, enums only hold names
- Only the first constant can
- Only via inheritance
- Yes, like EARTH(9.8) passing a gravity value
Answer: Yes, like EARTH(9.8) passing a gravity value. Enum constants can take constructor arguments, such as Planet(9.8).
What separates enum constants from member methods in the body?
- A comma
- A semicolon after the last constant
- A blank line
- Nothing
Answer: A semicolon after the last constant. When an enum also defines methods, a semicolon separates constants from members.
Which is the modern alternative to values() in newer Kotlin?
- allValues()
- constants()
- entries
- list()
Answer: entries. Newer Kotlin offers EnumName.entries as a modern alternative to values().
Continue this course
- Previous: Inheritance & Interfaces
- Next: Generics