I would also add that sealed interface
can be chosen instead of a class
to mark an object with additional characteristics and use it in the when
statement. For example let's say we have some number of classes that inherited from a sealed class Device
:
sealed class DeviceItem(val name: String) {
object Camera : DeviceItem("Camera")
object Lamp : DeviceItem("Lamp")
// ... etc, more devices
}
And we need to use an instance of DeviceItem
in when
statement, but we don't want to handle all the items, only specific items:
fun onDeviceItemClicked(item: DeviceItem) {
when (item) {
// ....
}
}
In this case we should either add all device items to the when
statement with an empty body for devices that we don't want to handle, and the code becomes cumbersome, or use else
statement to handle those device items with the empty body. But if we use else
we will not be notified of the error, when a new device item is added and requires some handling, which can lead to bugs. Starting from Kotlin 1.7
it will be a compilation error if when
operator is not exhaustive. So basically to handle such cases we can provide a sealed interface
and handle only items, which implement it:
sealed interface ClickableItem
sealed class DeviceItem(val name: String) {
object Camera : DeviceItem("Camera"), ClickableItem
object Lamp : DeviceItem("Lamp")
// ... etc, more devices
}
fun onDeviceItemClicked(item: ClickableItem) {
when (item) {
Camera -> { /* do something */ }
}
}
In this case when a new device item, which implements ClickableItem
interface, is added there will be a compilation error, saying that when
statement should be exhaustive and we must handle it.