Kotlin uses final by default: classes cannot be subclassed, and their methods and properties cannot be overridden. This protects class behavior from fragile base class changes. Use open explicitly when inheritance or overriding is part of the design. section 4.1.2
Allow one override, forbid another
open class RichButton : Clickable { final override fun click() { /* basic behavior */ } open fun animate() { /* customizable behavior */ } } class ThemedButton : RichButton() { override fun animate() { /* allowed */ } // override fun click() { /* compilation error */ } } The class must be open before it can be subclassed. Each member must also be open before a subclass can override it; final can close an otherwise overridable member. section 4.1.2
Use the modifiers together to make inheritance boundaries explicit:
- final prevents a class member from being overridden and is the default for Kotlin members. section 4.1.2
- open permits subclassing or overriding, but must be written on both the class and each customizable member. section 4.1.2
- override identifies a member that replaces a superclass or interface member; the replacement remains open unless marked final. section 4.1.2
- Java permits inheritance by default, whereas Kotlin requires deliberate opt-in, reducing unexpected coupling between base classes and subclasses. section 4.1.2
Listing 4.10 Forbidding an override
open class RichButton : Clickable {
final override fun click() { /* ... */ } #1
}
Inspect the compact declaration that forbids a subclass from overriding an inherited member. section 4.1.2


