Kotlin basics: inheritance modifiers. final, open, abstract and override.

Photo by Slim Emcee (UG) the poet Truth_From_Africa_Photography on Unsplash

Kotlin inheritance modifiers are similar toJava modifiers with different defaults.

final: default

The final modifier mark classes and methods as not allowed to be overridden. In Kotlin this is the default.

This decision was made to avoid fragile base class problem. It happens when a small change in base classes (super classes) make subclasses to malfunction. `

As we will see later, you need to mark a class with the open keyword to let it be extended. When we are changing a extended class the explicit open keyword, inform us that we should review the derived classes, and check if our changes in the super class are compatible with the subclasses.

SpecificButton can’t inherit Button because it is final. Moreover it can’t override click(), because it is final in Button.

You can change this default value if you mark them with the open modifier.


open modifier marks classes and methods as overridable. You need one per each method you want to be overridable.

Now Button is marked as open, so it can be inherited.

click() must be explicitly marked as open to be overridable.

Because doubleClick() is not marked as open it maintains its default modifier, final, so when we try to override it, we get an error.

override implies open in the super class, for that reason you need to add final if you want to stop allowing overrides in subclasses.

Classes inheriting from SuperSpecificButton won’t be able to override click()


The abstract modifier tell us that a class has at least one abstract method. An abstract method is a method that has no implementation.

You can’t create an instance of an abstract class.

The abstract method has to be marked also with the abstract modifier.

abstract methods are open by default and must be overridden.


We have seen this modifier in all the above examples. It marks the member as an override member of the superclass or interface. Kotlin code analysis will always remember you to add it in case is needed.

Overridden members are open by default.

Note: final by default and smart casting

Another important benefit of classes being final by default is that you can use smart casts with most properties without thinking about it. The compiler will do the casts for you.

Here is a small smart cast sample.

if (input is Int) {
return input + 1 // Here there is no need for explicit casting.

input does not need a cast in the if scope, because the compiler knows that input won’t change (is final) and therefore it will still be Int in the future.


Here is a table from the Kotlin in Action book that summarises these modifiers.

Android-Kotlin Developer

Android-Kotlin Developer