Labs ICT
Pro Login

Inheritance

Inheritance lets you build new classes on top of existing ones. In Kotlin, classes are closed by default — you have to explicitly opt in with the open keyword. It's a design choice that makes code safer and easier to reason about.

The open keyword

By default, every class in Kotlin is final — it can't be inherited. To allow inheritance, mark the class with open.


open class Animal(val name: String)

class Dog(name: String) : Animal(name) {
  fun bark() = println("$name says woof!")
}

fun main() {
  val dog = Dog("Buddy")
  dog.bark()
}
    

Use a colon : followed by the supertype. If the superclass has a constructor, you pass arguments right there.

Try it Yourself →

Overriding methods

Methods also need the open keyword to be overridable. Use override in the subclass.


open class Animal {
  open fun sound() = println("Some sound")
}

class Cat : Animal() {
  override fun sound() = println("Meow!")
}

fun main() {
  val cat = Cat()
  cat.sound()
}
    

If you don't mark the method as open in the parent, subclasses can't override it. Keeps your API predictable.

Try it Yourself →

Abstract classes

Abstract classes are open by nature — they define a contract that subclasses must fulfill.


abstract class Shape {
  abstract fun area(): Double
}

class Circle(val radius: Double) : Shape() {
  override fun area() = Math.PI * radius * radius
}

class Square(val side: Double) : Shape() {
  override fun area() = side * side
}

fun main() {
  val shapes = listOf(Circle(5.0), Square(4.0))
  shapes.forEach { println(it.area()) }
}
    

Abstract methods have no body. Every concrete subclass must provide an implementation. It's a promise, not an option.

Try it Yourself →