In Kotlin, override marks a member function or property that supplies a subclass or interface implementation in place of an inherited one. The modifier is mandatory: unlike Java’s optional @Override annotation, Kotlin requires an explicit declaration of that intent. This makes an accidental override—or a missing override after an API changes—a compile-time error. section 4.1.1 section 4.1.2
Listing 3.6 Overriding a member function
open class View { #1
open fun click() = println("View clicked") #2
}
class Button: View() { #3
override fun click() = println("Button clicked") #4
}
A base class must opt in to inheritance with open, and each member intended for replacement must also be open. Button then replaces View.click with its own implementation. section 3.3.4 section 4.1.2
Calls to overridden member functions use the runtime type of the object. A variable declared as View can hold a Button, and calling click invokes Button’s implementation. Kotlin is deliberately conservative about enabling this: classes and members are final by default, so inheritance and overriding must be designed explicitly. This helps avoid fragile base-class behavior when subclasses depend on assumptions that later base-class changes invalidate. section 3.3.4 section 4.1.2
Override behavior is controlled by a few related rules:
- Implementing an abstract interface member requires an override. An interface may also provide a default method body; a class can inherit it or redefine it. section 4.1.1
- When two interfaces provide the same default method, neither implementation wins. Provide an override explicitly, and select inherited implementations with super<Interface>.method(). section 4.1.1
- An overridden member is open to further overriding by default. Mark it final override when subclasses must not replace that implementation. section 4.1.2
- Properties can also implement interface properties with override, whether the value comes from a constructor property, a custom getter, or initialization. section 4.2.3
Resolving competing interface defaults
A Button that implements both Clickable and Focusable must override showOff when both interfaces define it. Its override can call each selected default implementation: class Button : Clickable, Focusable { override fun click() = println("I was clicked") override fun showOff() { super<Clickable>.showOff() super<Focusable>.showOff() } } The explicit implementation makes the combined behavior unambiguous. section 4.1.1
Do not confuse member overriding with extension functions. Extensions are declared outside a class and are resolved from the variable’s declared static type, even when its runtime value is a subtype. A member with the same signature takes precedence over an extension, and an extension cannot override that member. This matches extensions’ compilation as static Java functions with the receiver passed as an argument. section 3.3.4 section 9.2.1
Common overrides refine universal object behavior. Overriding toString produces useful logging or debugging output. Overriding equals defines value equality, which Kotlin uses for ==; a matching hashCode implementation is needed when instances are used in hash-based collections. Because equals comes from Any, it is an override rather than an extension. section 4.3.1 section 9.2.1


