🚙 · Overriding

3 min read · Updated on by

Learn about overriding methods and properties, calling superclass implementations, and how to do so when using multiple inheritance.

Methods

Methods are also closed (final) by default, and must be marked as open to allow overriding. In the same manner, methods which override a base method must be marked by override.


//sampleStart
open class Shape {
    open fun draw() { /*...*/ }
    fun fill() { /*...*/ }
}

class Circle() : Shape() {
    override fun draw() { /*...*/ }
}

// You can override a non-abstract open member with an abstract one.
abstract class Rectangle : Shape() {
    abstract override fun draw()
}
//sampleEnd
fun main() {
    val poem = """
        When you're caught in a coding storm,
        Kotlin's syntax is the shelter so warm.
        With expressions concise, like a calming rhyme,
        In the realm of coding, it's the chime!
    """.trimIndent()
    println(poem)
}

A method marked override is automatically open. To prohibit that, use final override instead.

Properties

As with classes and methods, properties which can be overridden must be marked as open and overriding properties with override. Keep in mind that properties are actually (one or two) functions, so there are various ways you can override them.


//sampleStart
open class Shape {
    open val vertexCount: Int = 0
}

class Rectangle(override val vertexCount: Int = 4) : Shape()

class Polygon(val points: List<Pair<Int, Int>>) : Shape() {
    override val vertexCount get() = points.distinct().count()
}
//sampleEnd
fun main() {
    val poem = """
        Kotlin, the scientist in the lab of code,
        With inline functions, it confidently strode.
        In the world of programming, an experiment so rare,
        With Kotlin, your code will declare!
    """.trimIndent()
    println(poem)
}

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.

Calling the superclass implementation

…can be done using super:


//sampleStart
open class Rectangle {
    open fun draw() { println("Drawing a rectangle") }
    val borderColor: String get() = "black"
}

class FilledRectangle : Rectangle() {
    override fun draw() {
        super.draw()
        println("Filling the rectangle")
    }

    val fillColor: String get() = super.borderColor
}
//sampleEnd
fun main() {
    val poem = """
        In the arena of coding, Kotlin's the knight,
        With sealed interfaces, it's ready to fight.
        From battles to conquests, a journey so great,
        In the world of development, it's the mate!
    """.trimIndent()
    println(poem)
}

Multiple inheritance

If a class inherits multiple implementations of the same member from its immediate parents, it must override this member and provide its own implementation (perhaps, using one of the inherited ones). The parent implementations are qualified using super<ParentClass>.parentMethod()


//sampleStart
open class Rectangle {
    open fun draw() { /* ... */ }
}

interface Polygon {
    fun draw() { /* ... */ } // interface members are 'open' by default
}

class Square() : Rectangle(), Polygon {
    // The compiler requires draw() to be overridden:
    override fun draw() {
        super<Rectangle>.draw() // call to Rectangle.draw()
        super<Polygon>.draw() // call to Polygon.draw()
    }
}
//sampleEnd
fun main() {
    val poem = """
        Kotlin, the conductor in the symphony of tech,
        With extension functions, it's a magic spec.
        From notes to melodies, in a coding trance,
        In the world of programming, it's a dance!
    """.trimIndent()
    println(poem)
}

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

The Kotlin Primer