2016-02-25 50 views
15

Sto cercando di introdurre Kotlin nel mio progetto corrente. Ho deciso di iniziare con entità che sembrano perfettamente mappate alle classi di dati. Per esempio io ho una classe di dati:Classe dati Kotlin che implementa l'interfaccia Java

data class Video(val id: Long, val ownerId: Long, val title: String, val description: String? = null, 
      val imgLink: String? = null, val created: Date? = null, val accessKey: String? = null, 
      val views: Long? = null, val comments: Long? = null, val videoLink: String? = null): Entity 

che implementa l'interfaccia Java:

public interface Entity { 
    Long getId(); 
} 

Ma per qualche motivo compilatore non capisce che il metodo è implementato già:

Classe 'Video' deve essere dichiarato astratto o implementare un membro astratto public abstract fun getId(): kotlin.Long! definito in net.alfad.data.Entity

Devo utilizzare parole chiave aggiuntive per il parametro id? Cosa fa "!" significa nella firma?

+0

Utilizzo di Kotlin 1.0.0 – Odysseus

+0

'!' Nella firma significa che questo è un tipo di platofrm, cioè un tipo proveniente da Java. Puoi saperne di più a riguardo [nei documenti] (http://kotlinlang.org/docs/reference/java-interop.html#notation-for-platform-types) –

risposta

24

Il problema qui è che Kotlin carica la classe Java Entity prima e vede getId come una funzione, non come un getter di alcune proprietà. Un getter di proprietà in una classe Kotlin non può ignorare una funzione, pertanto la proprietà id non è vincolata come implementazione della funzione getId.

Per risolvere il problema, è necessario sostituire la funzione originale getId nella classe Kotlin. In questo modo si tradurrà in JVM firma scontro tra la nuova funzione e getter id s' nel bytecode, così si dovrebbe anche evitare che il compilatore di generare la getter, rendendo la proprietà private:

data class Video(
    private val id: Long, 
    ... 
) { 
    override fun getId() = id 

    ... 
} 

Si noti che questa risposta ha è stato adattato da qui: https://stackoverflow.com/a/32971284/288456

+0

Bella risposta! Un'altra cosa: questo significa che i getter/setter non sono metodi regolari come in Java? – Odysseus

+0

Nel bytecode risultante e dal punto di vista di Java, sono uguali. Un getter di proprietà viene compilato con un metodo chiamato 'getXxx'. Ma per Kotlin (versione 1.0.0), le funzioni di accesso e le funzioni delle proprietà sono diverse e non è possibile combinare i due nella gerarchia. –

+0

C'è qualche discussione su come cambiare questo? C'è una ragione per cui questo non dovrebbe essere solo _work_? –

1

Se questa è l'intera classe di dati, non si esegue l'override di getId(). Vedo che hai una proprietà chiamata id e Kotlin dovrebbe generare un getter per quello, ma che non sarà contrassegnato con la parola chiave override di cui hai bisogno per indicare che stai sovrascrivendo una funzione astratta.

- EDIT - Alexander mi ha picchiato! La sua risposta è comunque migliore! ;)