liveBook · Manning

Open modifier

As explained in Kotlin in Action, 2E

The open modifier is a Kotlin declaration modifier that permits a class or member to be inherited or overridden.

Kotlin classes and members are final by default. Add open when inheritance or overriding is an intentional part of the design. Mark both the class and each overridable property or method explicitly; otherwise subclasses cannot extend or replace them. section 4.1.2

Allowing selected overrides

open class RichButton : Clickable { fun disable() { /* ... */ } open fun animate() { /* ... */ } override fun click() { /* ... */ } } class ThemedButton : RichButton() { override fun animate() { /* ... */ } override fun click() { /* ... */ } } Here, RichButton is inheritable, animate can be replaced, and disable remains unavailable for overriding. Because click overrides a member from Clickable, it is open to further subclasses unless explicitly marked final. section 4.1.2

Use the modifier with these boundaries in mind:

  • Mark a class open before declaring subclasses; mark every property or method intended for overriding open as well. section 4.1.2
  • Use final on an overriding member when its implementation must stop the override chain: final override fun click() { /* ... */ }. section 4.1.2
  • Do not expect open to make extension functions polymorphic. Extensions are resolved from the variable's declared type, unlike overridden member functions. section 3.3.4
  • Final-by-default declarations also support more reliable smart casts because subclasses cannot replace a final property with a custom accessor. 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
}

Inspect the compact declaration showing an open class, a non-overridable member, an open method, and an overridden interface member. section 4.1.2

How Kotlin in Action, 2E covers it

How deep it goes
Explains declarations, override chaining, extension-function limits, and smart-cast implications without developing compiler internals.
Examples
Uses RichButton and ThemedButton declarations, View and Button dispatch, and competing showOff extension functions.
What it assumes
Assumes familiarity with classes, members, interfaces, and subtypes while establishing Kotlin's final-by-default rule.
What you can do after
Apply it via Kotlin declarations to design controlled inheritance and diagnose unexpected extension-function dispatch.
How it connects
Connects inheritance, method overriding, final modifiers, abstract classes, extension functions, smart casts, and Java interoperability.

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.