All classes in Kotlin have a common superclass
Any, that is the default superclass for a class with no supertypes declared:
Any has three methods:
toString(). Thus, they are defined for all Kotlin classes.
By default, Kotlin classes are final: they can’t be inherited. To make a class inheritable, mark it with the
To declare an explicit supertype, place the type after a colon in the class header:
If the derived class has a primary constructor, the base class can (and must) be initialized right there, using the parameters of the primary constructor.
If the derived class has no primary constructor, then each secondary constructor has to initialize the base type using the
super keyword, or to delegate to another constructor which does that. Note that in this case different secondary constructors can call different constructors of the base type:
Kotlin requires explicit modifiers for overridable members and overrides:
override modifier is required for
Circle.draw(). If it were missing, the compiler would complain. If there is no
open modifier on a function, like
Shape.fill(), declaring a method with the same signature in a subclass is illegal, either with
override or without it. The
open modifier has no effect when added on members of a final class (i.e.. a class with no
A member marked
override is itself open, i.e. it may be overridden in subclasses. If you want to prohibit re-overriding, use
Overriding properties works in a similar way to overriding methods; properties declared on a superclass that are then redeclared on a derived class must be prefaced with
override, and they must have a compatible type. Each declared property can be overridden by a property with an initializer or by a property with a
You can also override a
val property with a
var property, but not vice versa. This is allowed because a
val property essentially declares a
get method, and overriding it as a
var additionally declares a
set method in the derived class.
Note that you can use the
override keyword as part of the property declaration in a primary constructor.
Derived class initialization order
During construction of a new instance of a derived class, the base class initialization is done as the first step (preceded only by evaluation of the arguments for the base class constructor) and thus happens before the initialization logic of the derived class is run.
It means that, by the time of the base class constructor execution, the properties declared or overridden in the derived class are not yet initialized. If any of those properties are used in the base class initialization logic (either directly or indirectly, through another overridden
open member implementation), it may lead to incorrect behavior or a runtime failure. When designing a base class, you should therefore avoid using
open members in the constructors, property initializers, and
Calling the superclass implementation
Code in a derived class can call its superclass functions and property accessors implementations using the
Inside an inner class, accessing the superclass of the outer class is done with the
super keyword qualified with the outer class name:
In Kotlin, implementation inheritance is regulated by the following rule: if a class inherits multiple implementations of the same member from its immediate superclasses, it must override this member and provide its own implementation (perhaps, using one of the inherited ones).
To denote the supertype from which the inherited implementation is taken, use
super qualified by the supertype name in angle brackets, e.g.
It's fine to inherit from both
Polygon, but both of them have their implementations of
draw(), so you need to override
Square and provide its own implementation that eliminates the ambiguity.