Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin interface a java class: Accidental override

Tags:

java

kotlin

I have a third party java library with a class like

public class ThirdParty  {
    public String getX() {
        return null;
    }
}

I also have an interface in kotlin like

interface XProvider {
    val x: String?
}

Now I want to extend the ThirdParty class and implement the XProvider interface. This has been working fine in my legacy java code:

public class JavaChild extends ThirdParty implements XProvider {}

However, I would like to write as much kotlin as possible and am trying to convert my java classes to kotlin. Sadly, the following does not work:

class KotlinChild: ThirdParty(), XProvider

Error is

class 'KotlinChild1' must be declared abstract or implement abstract member public abstract val x: String? defined in XProvider

However, if I do something like

class KotlinChild1: ThirdParty(), XProvider {
    override val x: String? = null
}

I get

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

What works is the following ugly work-around:

class KotlinChild: JavaChild()
like image 856
dpoetzsch Avatar asked May 10 '17 13:05

dpoetzsch


1 Answers

You have a naming conflict between the XProvider interface and the ThirdParty (abstract) class. This is caused my the Kotlin compililer which compiles

val x: String?

into a valid Java method because Java does not support the inheritance of variables or properties. The valid Java method will have the name "getX()". So you have a conflict between the XProvider.getX() and the ThirdParty.getX() method. So the solution might be to rename your property "x" in your XProvider class. Or you create a second class that contains an instance of ThridParty and implements XProvider. When val x: String is called you can provide the content by getting it from your ThirdParty instance.

Example:

class ThirdPartyImpl: XProvider {
    private val thridPartyInstance = ThridParty()
    override val x: String? = thirdPartyInstance.x
}
like image 67
Jonas Franz Avatar answered Nov 15 '22 12:11

Jonas Franz