Understanding Sealed Classes in Kotlin
Understanding Sealed Classes in Kotlin
Sealed classes are a powerful feature in Kotlin that allow you to represent restricted class hierarchies. They extend the capabilities of enum classes by allowing you to create multiple instances of each subclass, each potentially having its own state.
Defining a Sealed Class
To define a sealed class in Kotlin, you use the sealed
keyword. All subclasses of a sealed class must be declared in the same file as the sealed class itself. Here’s an example:
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
In this example, Expr
is a sealed class with three subclasses: Const
, Sum
, and NotANumber
.
Using Sealed Classes
Sealed classes are often used with when
expressions. Because the compiler knows all possible subclasses of a sealed class, it can check that all cases are covered in a when
expression, eliminating the need for an else
branch.
Here’s an example of how you might use a sealed class in a when
expression:
fun eval(expr: Expr): Double = when(expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
}
In this example, the when
expression covers all possible types of Expr
, so there’s no need for an else
branch. If you were to add another subclass to Expr
, the compiler would throw an error, reminding you to handle the new case in the when
expression.
Example Usage of Sealed Classes
Let’s take a look at a practical example. Suppose we’re building an app that handles network requests. We can represent the result of a network request as a sealed class:
sealed class Result
data class Success(val data: String) : Result()
data class Error(val error: Throwable) : Result()
In our code, we can then use a when
expression to handle each case:
fun handleResult(result: Result) {
when (result) {
is Success -> displayData(result.data)
is Error -> displayError(result.error)
}
}
In this example, if we were to add another subclass to Result
, the compiler would throw an error at the when
expression in handleResult
, reminding us to handle the new case.
This is one of the key advantages of sealed classes: they allow you to model your domain with greater precision and safety, reducing the likelihood of bugs in your code.