Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
Sealed Classes in Kotlin
Disclaimer: My articles are published under "Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)".
© Copyright: Simon Wirtz, 2017
Feel free to share.
'Sealed Classes' is a feature of the Kotlin programming language, which is also available in Scala for example. Although many people haven't heard of it yet, it's a quite simple feature worth knowing, which I'm going to explain in the following.
A sealed class can be subclassed and may include abstract methods which means sealed classes are abstract implicitly, although the documentation doesn't clearly say so. To actually make a class "sealed" we have to put the sealed modifier before its name, as we can see here:
sealed class MyClass
The important thing about sealed classes is that its subclasses must be declared in the same file as the sealed class itself.
The feature allows us to define class hierarchies that are restricted in its' types, i.e. subclasses. Since all subclasses need to be defined inside the file of the sealed class, there's no chance of unknown subclasses which the compiler doesn't know about.
Wait... Isn't this what an enum actually is?
Kotlin's sealed classes are some kind of "extension" of plain enums: As opposed to enums, subclasses of sealed classes can be instantiated multiple types and can actually contain state.
The main advantage of sealed classes reveals itself if it's used in
when expressions. Let's compare a normal class hierarchy to one of a sealed class handled in a when. First, we'll create a hierarchy of
Mammals and then put it into a method using a
else is mandatory, otherwise the compiler would complain with "
when expression must be exhaustive, add necessary
else branch". This is because it cannot verify that all possible cases, i.e. subclasses, are covered here. It may be possible that a subclass
Dog is available at any time that is still unknown at compile time.
Sealed "to the rescue"
What if we knew there wouldn't be other
Mammals in our application? We'd want to leave out that ``else` branch.
The problem of unknown subclasses can be avoided by
sealed classes. Let's modify the base class
Mammal, its' subclasses can remain the same.
sealed class Mammal(val name: String)
The code example from above now looks as follows:
We can simply omit the
else branch since the compiler can verify that all possible cases are covered. Only the subclasses defined in the file of the
sealed class exist, without exception.
What if a branch for at least on subsclass is being omitted?
Let's see what happens if we don't add a
when case for every subclass of our sealed class, e.g. do not have a
As one might expect, the compiler complains with a comprehensive error message: "Error: 'when' expression must be exhaustive, add necessary 'is Cat' branch or 'else' branch instead".
That's it. In conclusion really simple and handy, isn't it? Have fun trying it yourself!
Finally, if you want to read about sealed classes or any other feature in more detail I recommend the book Kotlin in Action.