2017-05-10 3 views
8

Ich habe eine dritte Partei Java-Bibliothek mit einer Klasse wieKotlin Schnittstelle eine Java-Klasse: versehentliche Überschreibung

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

ich auch eine Schnittstelle in Kotlin haben wie

interface XProvider { 
    val x: String? 
} 

Jetzt möchte ich die verlängern ThirdParty Klasse und implementieren Sie die XProvider Schnittstelle. Dies wurde gut funktioniert in meinem Vermächtnis Java-Code:

public class JavaChild extends ThirdParty implements XProvider {} 

Allerdings würde ich so viel Kotlin wie möglich zu schreiben und ich versuche, meine Java-Klassen zu konvertieren Kotlin. Leider ist die folgende nicht:

class KotlinChild: ThirdParty(), XProvider 

Fehler

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

jedoch ist, wenn ich etwas zu tun wie

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

I

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 

bekommen Was funktioniert, ist, das folgende hässliche Workaround:

class KotlinChild: JavaChild() 
+0

Welche Fehler bekommen Sie? – marstran

+0

Sorry, habe das vergessen. Ich aktualisierte die Frage – dpoetzsch

+0

Mögliches Duplikat von [Auflösen von versehentlichen Übersteuerungsfehlern in Kotlin] (http://stackoverflow.com/questions/32970923/resolving-accidental-override-errors-in-kotlin) – mfulton26

Antwort

2

Sie haben einen Namenskonflikt zwischen der XProvider-Schnittstelle und der ThirdParty (abstract) -Klasse. Dies wird meine die Kotlin compililer verursacht, die

val x: String? 

in eine gültige Java-Methode kompiliert, weil Java nicht die Vererbung von Variablen oder Eigenschaften unterstützen. Die gültige Java-Methode hat den Namen "getX()". Sie haben also einen Konflikt zwischen der XProvider.getX() und der ThirdParty.getX() -Methode. Die Lösung könnte also sein, Ihre Eigenschaft "x" in Ihrer XProvider-Klasse umzubenennen. Oder Sie erstellen eine zweite Klasse, die eine Instanz von ThridParty enthält und XProvider implementiert. Wenn val x: String aufgerufen wird, können Sie den Inhalt bereitstellen, indem Sie ihn von Ihrer ThirdParty-Instanz abrufen.

Beispiel:

class ThirdPartyImpl: XProvider { 
    private val thridPartyInstance = ThridParty() 
    override val x: String? = thirdPartyInstance.x 
} 
+1

Ich verstehe das Problem und sehe Ihre Problemumgehung. Ich habe viele Unterklassen von 'ThirdParty' (in meinem Fall' ParseObject') in Java, die ich jetzt in Kotlin konvertieren will und hier ist das Problem aufgetreten. Ihre Lösung würde nicht nur eine Menge Code ändern, sondern auch die externe Schnittstelle ('XProperty') meiner Bibliothek ändern. – dpoetzsch

+0

Was ist mit der zweiten Lösung? –

+0

Der Wrapper-Ansatz würde bedeuten, dass ich alle öffentlichen Methoden, die ich in meinem Projekt verwende, intern verpacken müsste, was meiner Meinung nach auch ziemlich hässlich ist. – dpoetzsch

Verwandte Themen