kotlin界面
Kotlin Interface supports default implementation. Which implies that we can have a default implementation to all the properties and functions defined in the Interface.
Kotlin接口支持默认实现。 这意味着我们可以对接口中定义的所有属性和函数具有默认实现。
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.
争论:许多开发人员并不赞赏在接口上具有默认实现。 我们不会讨论其优缺点,但我们对Kotlin如何实现这一目标更加感兴趣。
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.
注:为简单起见, 本文中使用 的 Java代码块是反编译的Java相当于生成的字节码由Kotlin编译器。
让我们开始吧 (Let’s get started)
Lets take a basic interface Wheels
with default implementations as an example to understand the subject.
让我们以带有默认实现的基本界面Wheels
为例来理解该主题。
interface Wheels {
fun getNumberOfWheels(): Int = 3
}
This interface allows us to skip the implementation in a Kotlin class 😎.
该接口使我们可以跳过Kotlin类the中的实现。
class KotlinCar : Wheels
Java问题 (The Java problem)
Java forces us to implement all the interface methods even if there are default implementation from the kotlin interface.
Java迫使我们实现所有接口方法,即使存在kotlin接口的默认实现。
Why do we care ?Though we love kotlin, sometimes we are forced to support legacy code using Java.
我们为什么在乎? 尽管我们喜欢kotlin,但有时我们还是不得不使用Java支持旧代码。
So how do we make use of the default implementation in a Java class ?
那么我们如何利用Java类中的默认实现呢?
DefaultImpls🎉 (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.
DefaultImpls
是编译器生成的类,用于保存默认实现。 它可以保存函数的默认方法及其默认参数值。 这就是koltin本机支持默认方法的原因。 以及为什么它甚至可以在Java 6上运行。
有趣的事实 (Fun fact)
DefaultImpls
can be refered directly from Java sources 👍, but not from KotlinDefaultImpls
可以直接从Java源代码👍从Kotlinrefered,但不You are not allowed to name a nested type as
DefaultImpls
in a kotlin interface 🙅♂️. Check this out您不能在kotlin界面🙅♂️中将嵌套类型命名为
DefaultImpls
。 看一下这个@JvmName
will not do the trick either@JvmName
也不会成功
Lets take an example of the Wheels
interface.
让我们以Wheels
界面为例。
![Image for post](https://miro.medium.com/max/9999/1*s_c6MXzAJWVkTubIoa7YFA.png)
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.
Java代码(反编译的字节码)显示创建了一个静态类DefaultsImpls
。 仅当至少有一个默认实现时才创建此类。
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.
在这种情况下-默认的getNumberOfWheels()
实现。 它以相同的名称,返回类型, instance
参数作为静态方法实现。 函数主体中的$this
引用引用instance
参数。
那么Kotlin如何做到这一点呢? (So how does kotlin do the trick ?)
![Image for post](https://miro.medium.com/max/9999/1*l9uitA26n0lhiTGR5AeIGQ.png)
If an implementing class doesn’t define getNumberOfWheels()
, then the compiler synthetic generates one just pointing to this static method.
如果实现类未定义getNumberOfWheels()
,则编译器综合会生成一个仅指向此静态方法的代码。
Java呢? (What about Java ?)
You can implement the same behavior in java by accessing the DefaultImpls
, but you are still forced to implement the methods.
您可以通过访问DefaultImpls
在Java中实现相同的行为,但是仍然必须实现这些方法。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b3151b319ff2212ca18a354dcb241d92.png)
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/817d9056a9a7069121989c428d755ccc.png)
The good news is, you can still access the default implementation by accessing the static class inside the Interface.
好消息是,您仍然可以通过访问Interface内部的静态类来访问默认实现。
Note: This is public only when accessing from Java.
注意:仅当从Java访问时,此属性才是公共的。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/d9709081a5bd3ed06cfbe875c8016742.png)
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).
啊! 我们还可以通过调用super.$functionName()
在Kotlin上执行相同的操作,但是DefaultImpls
类不能直接从Kotlin进行访问(这很明显)。
过度杀害-无用的实现 (OverKill — Useless implementation)
Here is an example of “Just because I can do it, I am doing it”
这是一个示例,“因为我能做,所以我在做”
![Image for post](https://miro.medium.com/max/9999/1*ySKLmAdIVrajt6evlJSlDw.png)
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 😊.
KotlinCar
和KotlinCar2
生成相同的字节码,因此请确保您不要过度使用它。 仅仅因为可以,并不意味着您应该😊。
Related topic:@JvmDefault
annotation.
相关主题 : @JvmDefault
批注 。
翻译自: https://proandroiddev.com/kotlin-interface-default-implementation-how-does-it-work-3af5056e0c03
kotlin界面