Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

In Kotlin, overriding a function is the mechanism by which a subclass provides a specific, polymorphic implementation for a method defined in its superclass or an implemented interface. Because Kotlin prioritizes explicit architectural boundaries, all classes and functions are final by default. To enable method overriding, developers must explicitly declare the base class’s inheritability, the base function’s extensibility, and the subclass’s intention to override.

Core Modifiers

The override mechanism relies on two primary keywords:
  • open: Applied to the base class itself to permit inheritance, and to the specific base function to explicitly permit subclasses to override it. If the base class is not marked open, it cannot be subclassed, rendering any open functions within it unreachable for overriding.
  • override: Applied to the subclass function to instruct the compiler to replace the base implementation. This modifier also enforces signature matching.
open class Base { // The class itself must be open to allow inheritance
    open fun execute() { // The function must be open to allow overriding
        println("Base implementation")
    }
}

class Derived : Base() {
    override fun execute() {
        println("Derived implementation")
    }
}

Default Parameters in Overrides

When overriding a function that declares default parameter values, the overriding function automatically inherits those default values from the base declaration. Kotlin strictly prohibits specifying default parameter values in the overriding function’s signature. Attempting to redefine or provide new default values alongside the override modifier results in a compiler error.
open class BaseComponent {
    open fun configure(timeout: Int = 3000) {
        println("Timeout: $timeout")
    }
}

class FastComponent : BaseComponent() {
    // ERROR: An overriding function is not allowed to specify default values for its parameters.
    // override fun configure(timeout: Int = 1000) { ... }
    
    override fun configure(timeout: Int) {
        println("Fast timeout: $timeout")
    }
}

Inheritance Rules and Mechanics

Implicit Openness When a function is marked with override, it remains implicitly open to any further subclasses in the inheritance hierarchy. Terminating the Override Chain To prevent subsequent subclasses from overriding a function further, the final modifier must be prepended to the override keyword.
open class Intermediate : Base() {
    final override fun execute() {
        println("Implementation locked at this level")
    }
}
Interface Defaults Unlike class methods, functions declared within an interface are implicitly open. If an interface function lacks a body, it is abstract and must be overridden. If it provides a default body, overriding is optional, but the open keyword is still not required in the interface declaration.
interface Executable {
    fun execute() // Implicitly abstract and open
    fun log() {   // Implicitly open, default implementation provided
        println("Log")
    }
}

Invoking Super Implementations

A derived class can invoke the base class’s implementation of an overridden function using the super keyword. This is evaluated statically based on the immediate superclass.
class ExtendedDerived : Base() {
    override fun execute() {
        super.execute() // Invokes Base.execute()
        println("Additional derived execution")
    }
}

Resolving Overriding Conflicts

When a class inherits from multiple types (e.g., a superclass and an interface, or multiple interfaces) that declare functions with identical signatures, the compiler mandates that the subclass explicitly override the conflicting function to resolve the ambiguity. To invoke a specific base implementation within the resolved function, Kotlin uses angle bracket syntax <BaseType> alongside the super keyword.
interface Alpha {
    fun process() { println("Alpha process") }
}

interface Beta {
    fun process() { println("Beta process") }
}

class Composite : Alpha, Beta {
    override fun process() {
        super<Alpha>.process() // Explicitly routes to Alpha's implementation
        super<Beta>.process()  // Explicitly routes to Beta's implementation
    }
}
Master Kotlin with Deep Grasping Methodology!Learn More