androidengineers.Book a session

Object-Oriented Programming

Inheritance, open/final, and Overriding

article15 minMedium

Open inheritance only where substitution makes sense

Kotlin classes and members are final unless marked open or abstract. An override should honor the base contract: callers using the base type must still receive valid behavior.

open class Formatter {
    open fun format(topic: String): String = topic.trim()
}

class UppercaseFormatter : Formatter() {
    override fun format(topic: String): String = super.format(topic).uppercase()
}

fun main() {
    val formatter: Formatter = UppercaseFormatter()
    check(formatter.format(" Kotlin ") == "KOTLIN")
}

Dynamic dispatch selects the subclass implementation. The super call deliberately reuses the base normalization step. Do not expose inheritance solely to reuse a few lines; composition often makes independent policies easier to test and replace.

Avoid requiring clients to know which subclass they received. If one implementation throws for inputs accepted by the base contract, the hierarchy is misleading.

Exercise

Create a formatter that adds a prefix while preserving trimming. Then implement the same behavior by wrapping another formatter.

Check: compare which design permits combining uppercase and prefix policies without adding a subclass for every combination.

Reference: Inheritance

YOUR LEARNING JOURNEY

0 of 110 available lessons completed

Progress saved in this browser. No account needed.
Inheritance, open/final, and Overriding | Kotlin Core Programming | Android Engineers