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.