Kotlin接口java类:意外覆盖

dpo*_*sch 10 java kotlin

我有一个类似的第三方java库

public class ThirdParty  {
    public String getX() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在kotlin中也有一个界面

interface XProvider {
    val x: String?
}
Run Code Online (Sandbox Code Playgroud)

现在我想扩展ThirdParty类并实现XProvider接口.这在我的遗留Java代码中运行良好:

public class JavaChild extends ThirdParty implements XProvider {}
Run Code Online (Sandbox Code Playgroud)

但是,我想写尽可能多的kotlin并尝试将我的java类转换为kotlin.可悲的是,以下不起作用:

class KotlinChild: ThirdParty(), XProvider
Run Code Online (Sandbox Code Playgroud)

错误是

class 'KotlinChild1' must be declared abstract or implement abstract member public abstract val x: String? defined in XProvider
Run Code Online (Sandbox Code Playgroud)

但是,如果我做的话

class KotlinChild1: ThirdParty(), XProvider {
    override val x: String? = null
}
Run Code Online (Sandbox Code Playgroud)

我明白了

error: accidental override: The following declarations have the same JVM signature (getX()Ljava/lang/String;)
    fun <get-x>(): String?
    fun getX(): String!
        override val x: String? = null
Run Code Online (Sandbox Code Playgroud)

有效的是以下丑陋的解决方法:

class KotlinChild: JavaChild()
Run Code Online (Sandbox Code Playgroud)

Jon*_*anz 2

XProvider 接口和 ThirdParty(抽象)类之间存在命名冲突。这是由于我的 Kotlin 编译器编译的

val x: String?
Run Code Online (Sandbox Code Playgroud)

转换为有效的 Java 方法,因为 Java 不支持变量或属性的继承。有效的 Java 方法的名称为“getX()”。因此, XProvider.getX() 和 ThirdParty.getX() 方法之间存在冲突。因此,解决方案可能是在 XProvider 类中重命名属性“x”。或者您创建第二个类,其中包含 ThridParty 的实例并实现 XProvider。当 val x: String 被调用时,您可以通过从 ThirdParty 实例获取内容来提供内容。

例子:

class ThirdPartyImpl: XProvider {
    private val thridPartyInstance = ThridParty()
    override val x: String? = thirdPartyInstance.x
}
Run Code Online (Sandbox Code Playgroud)