ProgrammingSenior Kotlin Developer

How does the 'super' keyword work in Kotlin and how is it different from its usage in Java? In what cases will there be ambiguities when multiple interfaces are implemented and how to resolve them?

Pass interviews with Hintsage AI assistant

Answer

In Kotlin, the super keyword is used to refer to the implementation of a method or property in a superclass or implemented interface. Unlike Java, Kotlin allows you to explicitly specify which interface or class to call the implementation of the method from, which is especially important in case of conflicts between several interfaces with the same methods.

Feature: If a class implements multiple interfaces where a method with the same signature is defined and there is a default implementation, you need to explicitly state which implementation to use.

Example:

interface A { fun foo() = println("A") } interface B { fun foo() = println("B") } class C : A, B { override fun foo() { super<A>.foo() // Explicitly calling A.foo super<B>.foo() // Explicitly calling B.foo } }

This is not directly supported in Java (Java doesn't allow interfaces to have fields/method implementations until Java 8, and even in Java 8 the mechanisms are different).

Trick Question

"Can you access the super implementation of a method through multiple levels of inheritance in Kotlin?"

  • Common mistake: people think they can access the implementation through an intermediate class: super<Intermediate>.foo(), but this is not the case — you can only call the immediate superclass or interface that directly implements this method.

Example:

open class Base { open fun foo() = println("Base") } open class Mid : Base() { override fun foo() { println("Mid"); super.foo() } } class Child: Mid() { override fun foo() { super.foo() // will call Mid.foo() // super<Base>.foo() — compile error } }

Examples of Real Errors due to Lack of Knowledge of the Subject


Story

In a large project, the interfaces Logger and Auditor both defined the method record(). When implementing a class that inherited both interfaces, the programmer did not explicitly override record(), resulting in a compile error "Class must override public open fun record()". They had to implement the method manually and explicitly delegate to the corresponding interface.


Story

When trying to call a superclass method implementation through several intermediate layers (e.g., super<Base>.foo()), a compile error occurred. The developer was unaware of Kotlin constraints and could not understand why the direct call was not possible.


Story

After an API update, one of the interfaces added a default function implementation that conflicted with another interface. The old code no longer compiled due to implementation conflicts — the programmer had to resolve the conflict explicitly by implementing the method themselves and choosing which superinterface implementations to call within.