Today I came across the Kotlin Sealed Class which I had never heard of before. After some research, I found that this concept is nothing new and is also available in Scala for example. So, yet another Scala feature JetBrains considered relevant and suitable for Kotlin? I like that 🙂 Read this post if you're interested in more Kotlin features.
Actually, this is a quite simple feature, which I'm going to explain in the following.
Kotlin Sealed Class - Feature Explanation
A sealed
class can be subclassed and may include abstract
methods, which means that 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
Restriction
The important thing about sealed classes is that its subclasses must be declared in the same file as the sealed class itself.
Benefit
The feature allows us to define class hierarchies that are restricted in their 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?
A Kotlin sealed class is some kind of extension of plain enums: As opposed to enums, subclasses of sealed classes can be instantiated multiple times and can actually contain state.
Use Case
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 Mammal
s and then put it in a method with a when
:
open class Mammal(val name: String)
class Cat(val catName: String) : Mammal(catName)
class Human(val humanName: String, val job: String) : Mammal(humanName)
fun greetMammal(mammal: Mammal): String {
when (mammal) {
is Human -> return "Hello ${mammal.name}; You're working as a ${mammal.job}"
is Cat -> return "Hello ${mammal.name}"
else -> return "Hello unknown"
}
}
The else
is mandatory, otherwise, the compiler will complain. This is because it just 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 which is unknown at compile time.
Sealed "to the rescue"
But what if we knew there wouldn't be other Mammal
s in our application? We'd want to leave out the elseÂ
block.
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)
Now we can simply omit the else
clause since the compiler can verify that all possible cases are covered because only the subclasses in the file of the sealed
class exist, without exception. The method now looks as follows:
fun greetMammal(mammal: Mammal): String {
when (mammal) {
is Human -> return "Hello ${mammal.name}; You're working as a ${mammal.job}"
is Cat -> return "Hello ${mammal.name}"
// `else` clause not required, all the cases covered
}
}
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 class in Kotlin in more detail I recommend the book Kotlin in Action to you!
Simon
Simon is a software engineer with 9+ years of experience developing software on multiple platforms including the JVM and Serverless environments. He currently builds scalable distributed services for a decision automation SaaS platform. Simon is a self-appointed Kotlin enthusiast.