Skip to content
tezvyn:

Kotlin Inheritance: Open for Extension, Closed by Default

Source: kotlinlang.orgMediumHow cards are made

Kotlin Inheritance: Open for Extension, Closed by Default

In Kotlin, classes are final by default. Think of inheritance as an opt-in feature you enable with the open keyword. Use it to create specialized versions of a base class, like a Student from a Person.

Why it exists

Inheritance enables code reuse and polymorphism by letting one class acquire the properties and methods of another. However, unrestricted inheritance can create fragile, tightly-coupled systems. Kotlin's design makes inheritance an intentional act to encourage more robust code.

The mental model

Think of Kotlin classes as sealed boxes. By default, you can't alter or extend them. To allow inheritance, you must explicitly mark a class as open. This "final by default" philosophy promotes composition over inheritance and makes code easier to reason about, as a class's behavior isn't changed by a subclass unless it was explicitly designed for it.

How it works

All Kotlin classes implicitly inherit from Any, which provides equals(), hashCode(), and toString(). To inherit from another class, declare the supertype after a colon: class Derived : Base(). The base class and any members you wish to override must be marked open. The derived class must call the base class constructor. To override a member, you must use the override keyword. This overridden member is itself open for further subclassing unless you mark it final override. You can override a val property with a var, but not the reverse.

When to use it

Use inheritance for clear "is-a" relationships where you need to share implementation, not just a contract. A Circle "is-a" Shape. It's also necessary when a framework requires it, like extending android.view.View. Before creating a class hierarchy, always consider if an abstract class or an interface (which are open by default) would be a better fit.

When not to use it

Avoid inheritance if an interface or composition is a better fit. If classes only share a common contract but not a common implementation, use an interface. For "has-a" relationships, like a Car that has an Engine, prefer composition by holding an Engine instance rather than inheriting from it. Kotlin's final default nudges you to consider these alternatives first.

One canonical example

To create a specialized Student class from a Person class, you must mark Person and its introduce method as open. The Student class then uses override to provide its own implementation.

open class Person(val name: String) { open fun introduce() { println("Hello, my name is $name.") } }

class Student(name: String, val school: String) : Person(name) {

override fun introduce() { println("Hi, I'm name, and I study at school.") } }

Interview question

What is the primary reason Kotlin classes are final by default?

  • a.To encourage explicit design for inheritance and promote composition over inheritance.Correct
  • b.To optimize runtime performance by allowing the compiler to inline method calls more aggressively.
  • c.To ensure that all class properties are immutable unless explicitly marked as mutable.
  • d.To prevent developers from creating circular dependencies in class hierarchies.
Why?

The card states that Kotlin's design makes inheritance an intentional act to encourage more robust code and promotes composition over inheritance. Option A directly captures these core reasons. Option C is incorrect as 'final by default' relates to inheritance, not the mutability of properties, which is controlled by 'val' and 'var'.

Just read this? Test yourself on what you have been reading.

Read the original → kotlinlang.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on kotlin — each one lists the topics its interview covers.

See open roles