Kotlin Interface Default Implementation — How does it work ?

Kotlin Interface supports default implementation. Which implies that we can have a default implementation to all the properties and functions defined in the Interface.

The debate:
Having default implementation on interface is not appreciated by many developers. We are not going to discuss about the pros and cons, but we are more interested in how Kotlin has achieved this.

Note: To keep things simple, the java code blocks used in this article is the decompiled java equivalent of the generated byte-code by the Kotlin compiler.

Let’s get started

Lets take a basic interface Wheels with default implementations as an example to understand the subject.

interface Wheels {
    fun getNumberOfWheels(): Int = 3
}

This interface allows us to skip the implementation in a Kotlin class ????.

class KotlinCar : Wheels

The Java problem

Java forces us to implement all the interface methods even if there are default implementation from the kotlin interface.

Why do we care ?
Though we love kotlin, sometimes we are forced to support legacy code using Java.

So how do we make use of the default implementation in a Java class ?

DefaultImpls ????

The DefaultImpls is a compiler generated class to hold the default implementations. It can hold default methods for functions and their default parameter values. This is the reason why koltin supports default methods natively. And why it can even work on Java 6.

Fun fact

  • DefaultImpls can be refered directly from Java sources ????, but not from Kotlin

  • You are not allowed to name a nested type as DefaultImpls in a kotlin interface ????‍♂️. Check this out

  • @JvmName will not do the trick either

Lets take an example of the Wheels interface.

The java code (decompiled bytecode) shows that a static class DefaultsImpls is created. This class will be created only if there is atleast one default implementation.

In this case — the default getNumberOfWheels() implementation. It is implemented as a static method by the same name, return type, an instance parameter . $this references in the function body are refering to the instance parameter.

So how does kotlin do the trick ?

If an implementing class doesn’t define getNumberOfWheels(), then the compiler synthetic generates one just pointing to this static method.

What about Java ?

You can implement the same behavior in java by accessing the DefaultImpls , but you are still forced to implement the methods.

The good news is, you can still access the default implementation by accessing the static class inside the Interface.

Note: This is public only when accessing from Java.Ah! we can also do the same on Kotlin by calling super.$functionName() , but the DefaultImpls class is not directly accessible from Kotlin (It’s obvious).

OverKill — Useless implementation

Here is an example of “Just because I can do it, I am doing it”

KotlinCar and KotlinCar2 generates the same byte code, so make sure you don’t overdo it. Just because you can, doesn’t mean you should ????.

https://proandroiddev.com/kotlin-interface-default-implementation-how-does-it-work-3af5056e0c03

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/108459665