liveBook · Manning

Inheritance

As explained in Kotlin in Action, 2E

Inheritance is the language mechanism by which a class derives members and behavior from a superclass.

Inheritance lets a Kotlin class derive behavior and members from a superclass. Kotlin makes classes and members final by default, so inheritance must be enabled deliberately with open. section 4.1.2

Listing 4.8 Declaring an open class with an open method
open class RichButton : Clickable {        #1
    fun disable() { /* ... */ }            #2
    open fun animate() { /* ... */ }       #3
    override fun click() { /* ... */ }     #4
}

Declare the class open before subclassing it, then mark only overridable members open; final members preserve basic behavior. section 4.1.2

A subclass names its superclass after a colon and calls the superclass constructor with parentheses. It can override only open members, and Kotlin requires the override modifier explicitly. section 4.1.2 section 4.1.1

Listing 4.9 Declaring a subclass of an open class that overrides open methods
class ThemedButton : RichButton() {         #1
    override fun animate() { /* ... */ }    #2
    override fun click() { /* ... */ }      #3
    override fun showOff() { /* ... */ }    #4
}

The subclass changes animate and click while inheriting other behavior from RichButton; overriding click is valid because the base member is open. section 4.1.2

Kotlin inheritance has several practical boundaries:

  • A class can extend only one class, but it can implement multiple interfaces. section 4.1.1
  • An overriding member is open by default unless it is marked final, which prevents further overrides. section 4.1.2
  • Abstract classes may require subclasses to implement abstract properties and functions while also supplying concrete or open members. section 4.1.2
  • When inherited interface implementations conflict, the implementing class must override the member and may call each interface implementation explicitly with super. section 4.1.1

A controlled button hierarchy

open class RichButton : Clickable { fun disable() { /* basic behavior remains fixed */ } open fun animate() { /* subclasses may customize */ } override fun click() { /* inherited interface behavior */ } } class ThemedButton : RichButton() { override fun animate() { /* theme-specific animation */ } } RichButton exposes an extension point for animation without allowing subclasses to override disable. This deliberate boundary reduces fragile-base-class risks. section 4.1.2

How Kotlin in Action, 2E covers it

How deep it goes
Explains open, final, override, and abstract members with examples, stopping short of broader inheritance design guidance.
Examples
Uses Clickable, Button, RichButton, ThemedButton, and conflicting default interface methods to demonstrate inheritance behavior.
What it assumes
Assumes classes and interfaces, while introducing Kotlin's hierarchy syntax and explicit overriding rules.
What you can do after
Apply it via Kotlin's open, override, final, and abstract modifiers to build selectively extensible class hierarchies.
How it connects
Connects inheritance with classes, interfaces, abstract classes, visibility, access modifiers, and sealed classes.

Also explained in

Compare how 19 books explain inheritance →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.