Override Conflicts in Kotlin Interface Inheritance

Home » Kotlin » Override Conflicts in Kotlin Interface Inheritance

Kotlin’s interface inheritance is one of the top-notch features of the language, but sometimes it can be really tricky to handle multiple implementations of the same methods. This is where override conflicts come into play. How do we handle override conflicts in Kotlin? In this Kotlin tutorial, we will explore how to properly override methods with the same name.

To avoid ambiguity, Kotlin requires us to explicitly mark the overridden method using the override keyword. This ensures that the developer is aware of the conflict and provides an unambiguous implementation. The use of the override keyword is not optional when a method is implementing an interface’s contract with a conflicting method name.

interface InterfaceA {
    fun commonMethod() {
        // Some default implementation
    }
}

interface InterfaceB {
    fun commonMethod() {
        // Some other default implementation
    }
}

class MyClass : InterfaceA, InterfaceB {
    override fun commonMethod() {
        // Explicitly provide a specific implementation
        // to resolve the override conflict
    }
}

fun main(){
    
}

Override Conflicts in Kotlin Interface Inheritance

If a class inherits from a superclass that provides an implementation of a conflicting method, we can call the superclass method using the super keyword. This approach helps retain the behavior defined in the superclass and ensures consistent behavior across the inheritance hierarchy.

open class MyBaseClass {
    open fun commonMethod() {
        // Some default implementation
    }
}

interface InterfaceA {
    fun commonMethod()
}

class MyClass : MyBaseClass(), InterfaceA {
    override fun commonMethod() {
        // Call the superclass implementation
        super.commonMethod()
        // Provide additional specific implementation if needed
    }
}
fun main() {
    val kotlin = "🙂"
    println(kotlin)
}

When declaring multiple types in your supertype list, it’s possible to inherit more than one implementation of the same method.

Override conflicts in Kotlin : Method Overriding Ambiguities

Write the following code in Kotlin Play ground

package `interface`

interface Animal{
    fun species(){
        println("Animals are here!")
    }
    fun details()
}
interface Bird{
  fun species() {
      println("Birds are here!")
  }
  fun details() {
      println("I lke birds")
  }
}
class Zoo: Animal{
    override fun details() {
        println("Zoo animals")
    }
}
class Place: Animal, Bird{
    override fun species() {
       super<Animal>.species()
       super<Bird>.species()
    }

    override fun details() {
        super<Bird>.details()
    }

}

fun main() {
    val place = Place()
    place.species()
    place.details()
}

Animals are here!
Birds are here!
I lke birds

In the above example, both Interfaces Animal and Bird declare species() and details(). While both of them implement species(), only Bird implements details(). (Note: details() is not marked as abstract in Animal, as this is the default for interfaces when the functions have no body.)

Access by Name :

super<Animal>.species()

Kotlin’s interface inheritance offers a flexible mechanism for designing modular and reusable code. While handling override conflicts may seem daunting at first, it is essential to remember that Kotlin’s strict approach ensures clear intentions and unambiguous code.

By understanding the hierarchy, explicitly overriding methods, utilizing superclass implementations, and embracing composition when necessary, developers can effectively navigate and resolve Kotlin override conflicts of interface inheritance.

This enables us to harness the true power of Kotlin’s object-oriented paradigm and build robust, maintainable, and scalable applications.

You may also like...