Inheritance
Prerequisites: Classes and objects
Inheritance lets a class build on another class. The subclass gets the superclass's properties and methods and can add or change behavior.
In Kotlin, classes are final by default — they can't be inherited
from unless marked open. This is deliberate: designing a class for
inheritance takes care, so you opt in explicitly.
Example
open class Vehicle(val wheels: Int) {
open fun describe() = "A vehicle with $wheels wheels"
}
class Bicycle : Vehicle(2) {
override fun describe() = super.describe() + " that you pedal"
}
class Car(val brand: String) : Vehicle(4) {
override fun describe() = "A $brand car"
}
fun main() {
val vehicles: List<Vehicle> = listOf(Bicycle(), Car("Volvo"))
for (vehicle in vehicles) {
println(vehicle.describe())
}
}
Expected output
A vehicle with 2 wheels that you pedal
A Volvo car
open classallows subclasses;open funallows overriding.class Bicycle : Vehicle(2)inherits fromVehicle, passing2to its constructor.overrideis required when replacing a method, so you can't override something by accident.super.describe()calls the superclass's version.- A
List<Vehicle>can hold any subclass, and each element uses its owndescribe()— this is polymorphism.
Abstract classes
An abstract class can't be created directly; it exists to be subclassed, and can declare methods that subclasses must implement:
abstract class Shape {
abstract fun area(): Double
fun describe() = "Area: ${"%.2f".format(area())}"
}
class Square(val side: Double) : Shape() {
override fun area() = side * side
}
class Circle(val radius: Double) : Shape() {
override fun area() = Math.PI * radius * radius
}
fun main() {
println(Square(3.0).describe())
println(Circle(1.0).describe())
}
Area: 9.00
Area: 3.14
Prefer composition and interfaces
Deep inheritance chains become hard to follow and change. Kotlin code usually shares behavior through interfaces (next lesson) and by having one object hold another (composition), keeping inheritance for true "is a kind of" relationships.
Common mistakes
- Forgetting
open:This type is final, so it cannot be extended. - Forgetting
override: the compiler reports that the method hides a member of the superclass and needs theoverridemodifier.