Phase 3 · Object-Oriented KotlinModule 16~38 min read

Inheritance & Interfaces

Extend classes with open/override and design contracts with interfaces.

What you'll learn

Inheritance lets classes build on one another, and interfaces define contracts that many classes can fulfil. Kotlin adds a safety twist: classes are closed to inheritance by default, so extension is always a deliberate choice.

By the end you'll be able to:

  • Open a class for inheritance and subclass it
  • Override methods (and know why override is required)
  • Use abstract classes
  • Define and implement interfaces, including default methods

open & inheritance

Unlike Java, Kotlin classes are final by default — you can't subclass them unless they're marked open. This prevents fragile inheritance you didn't intend. To inherit, the parent must be open, and you list it after a colon, calling its constructor:

Final by default

By default: final

class Animal
// class Dog : Animal()  ← ERROR: Animal is final

Kotlin classes and methods are closed to inheritance by default.

Opt in with open

open class Animal
class Dog : Animal()  // ✓ works

You explicitly mark what may be subclassed or overridden.

Inheritance.kt
open class Animal(val name: String) {      // 'open' allows subclassing
    open fun speak() = "$name makes a sound" // 'open' allows overriding
}

class Dog(name: String) : Animal(name) {     // : calls the parent constructor
    override fun speak() = "$name barks"      // 'override' is REQUIRED
}

println(Dog("Rex").speak())   // Rex barks
println(Animal("Thing").speak())

Overriding

To replace a parent's method, the parent method must be open, and the child must use the override keyword — it's not optional as in Java. This makes overriding explicit and catches mistakes. Use super.method() to call the parent's version from within the override.

Abstract classes

An abstract class can't be instantiated and can declare abstract members with no body that subclasses must implement — while also providing concrete shared code. (Abstract members are implicitly open.)

Shape.kt
abstract class Shape {
    abstract fun area(): Double               // no body — subclasses must implement
    fun describe() = "Area is ${area()}"      // a concrete method
}

class Circle(val r: Double) : Shape() {
    override fun area() = 3.14159 * r * r
}

println(Circle(2.0).describe())

Interfaces

An interface is a contract. A class can implement many interfaces (unlike single class inheritance), listing them after the colon. Kotlin interfaces can even provide default implementations — methods with a body that implementers get for free:

Interfaces.kt
interface Drawable {
    fun draw()
    fun describe() = "I can be drawn"         // interfaces can have default methods
}

interface Clickable {
    fun onClick()
}

class Button : Drawable, Clickable {          // implement MANY interfaces
    override fun draw() = println("Drawing")
    override fun onClick() = println("Clicked")
}

val b = Button()
b.draw()
b.onClick()
println(b.describe())

Abstract class or interface?

Use an interface for a capability that many unrelated types can have (like Comparable or Clickable), and a class can implement several. Use an abstract class for a shared base with common state and a single "is-a" hierarchy. And remember Kotlin's advice: favour composition over deep inheritance.

Recap & quick check

Key takeaways

  • Kotlin classes are final by default; mark them 'open' to allow subclassing.
  • Inherit with ClassName : Parent(...); the override keyword is required (not optional).
  • Abstract classes can't be instantiated and declare abstract members subclasses must implement.
  • A class can implement many interfaces; interfaces can carry default method implementations.
  • Interface = a capability many types can have; abstract class = a shared base for one hierarchy.

Quick check

1. Why can't you subclass a normal Kotlin class by default?

2. What keyword is required when replacing a parent method?

3. How many interfaces can a class implement?

4. Can a Kotlin interface provide a method body?

5. When would you choose an interface over an abstract class?

Great — you can model hierarchies and contracts now. Next up: Module 17 — Objects, Companion Objects & Singletons.