2017-08-26 1 views
1

Ich bin neu in Kotlin und wirklich besorgt, ob ich die richtige Syntax schreibe oder nicht. Ich habe eine super Klasse und ich möchte eine generische abstrakte Funktion wie folgt schreiben.Kotlin - abstrakte Funktion mit generischem Rückgabetyp

abstract class A { 
    abstract fun <T> getText() : Test<T> 
} 

class B : A() { 
    override fun <T> getText(): Test<T> { 
     return Test1() // Error - Required Test<T>, found Test1 
    } 
} 

class C : A() { 
    override fun <T> getText(): Test<T> { 
     return Test2() // Error - Required Test<T>, found Test2 
    } 
} 

class Test1 : Test<String>() { 

} 

class Test2 : Test<Int>() { 

} 

Kann ich diese Art von Problem mit einer richtigen Syntax lösen. Ich schätze, ich mache einen Fehler? Kann mir bitte jemand helfen?

Antwort

3

für dieses ist die Antwort übereinstimmen Sie suchen:

abstract class A<T> { 
    abstract fun getText() : Test<T> 
} 

class B : A<String>() { 
    override fun getText(): Test<String> = Test1() 
} 

class C : A<Int>() { 
    override fun getText(): Test<Int> = Test2() 
} 

class Test1 : Test<String>() 
class Test2 : Test<Int>() 
open class Test<T> 

Sie müssen nur den Parameter T von der Methodensignatur in die Klasse verschieben.

Bonus: Ich aktualisierte das obige Schnipsel zu idiomatischen Kotlin

3

Was Sie tun, nicht richtig sein kann, weil es den folgenden Code erlauben würde:

val test: Test<Int> = B().getText() 

B().getText() versucht Test1() zurückzukehren, was Test<String> ist. Aber weil der Rückgabetyp irgendetwas sein kann, ist es gültig. Dies bricht das Typsystem.

2

Wahrscheinlich möchten Sie den Typ von der Klasse statt der Methode erzwingen, aufgrund des Beispiels von Kiskae.

Zum Beispiel:

abstract class A<T> { 
    abstract fun getText() : Test<T> 
} 

erweitert werden kann

class B : A<String>() ... 

verwendet, die den Typ für Test1

Verwandte Themen