Middle
What is the difference between sealed classes and abstract classes in Kotlin?
sobes.tech AI
Answer from AI
The main difference between sealed classes and abstract classes is that sealed classes restrict the inheritance hierarchy within a single file or module (for Kotlin 1.5+). Inheritors of a sealed class must be declared in the same file as the sealed class itself, which ensures exhaustive checking when using when expressions.
Differences:
- Inheritance:
- Abstract classes can be inherited anywhere in the project.
- Sealed classes can only be inherited within the same file (before Kotlin 1.5) or within the same module (with Kotlin 1.5+).
- Usage with
when:- When using
whenwith a sealed type, the compiler can verify that all possible subtypes are considered, makingwhenexhaustive and eliminating the need to explicitly specify anelsebranch if all subtypes are handled. - With abstract classes, the compiler cannot guarantee exhaustiveness, so an
elseis often required.
- When using
- Creating instances:
- Neither abstract nor sealed classes can be instantiated directly.
- Members:
- Both abstract and sealed classes can have abstract and non-abstract members.
Example of a sealed class:
sealed class Result<out T> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val message: String) : Result<Nothing>()
}
fun processResult(result: Result<Int>) {
when (result) {
is Result.Success -> {
// Handling success
println("Success: ${result.data}")
}
is Result.Error -> {
// Handling error
println("Error: ${result.message}")
}
// No else needed if all subclasses are handled
}
}
Example of an abstract class:
abstract class Shape {
abstract fun area(): Double
}
class Circle(val radius: Double) : Shape() {
override fun area(): Double = Math.PI * radius * radius
}
class Rectangle(val width: Double, val height: Double) : Shape() {
override fun area(): Double = width * height
}
fun calculateArea(shape: Shape): Double {
return shape.area()
}
When to use:
- Sealed classes: Ideal for representing a limited set of states or types where exhaustive checking in
whenexpressions is needed. Often used for modeling operation results (success/failure), UI states, events. - Abstract classes: Suitable for defining common functionality and contracts for a group of related classes that can be inherited anywhere in the project.
In summary, sealed classes provide stricter control over the inheritance hierarchy and improve safety and readability when handling a limited set of subtypes.