2014-10-18 14 views
41

Le classi di dati sembrano essere la sostituzione ai POJO vecchio stile in Java. È abbastanza prevedibile che queste classi consentano l'ereditarietà, ma non vedo alcun modo conveniente per estendere una classe di dati. Ho bisogno di qualcosa di simile:Estendi la classe di dati in Kotlin

open data class Resource (var id: Long = 0, var location: String = "") 
data class Book (var isbn: String) : Resource() 

Il codice di cui sopra non riesce a causa di scontro di component1() metodi. Lasciare l'annotazione data in una sola delle classi non funziona anche.

Forse c'è un altro idioma per estendere le classi di dati?

UPD: Potrei annotare solo la classe child child, ma l'annotazione data gestisce solo le proprietà dichiarate nel costruttore. Cioè, avrei dovuto dichiarare tutte le proprietà del genitore open e sovrascrivere loro, che è brutto:

open class Resource (open var id: Long = 0, open var location: String = "") 
data class Book (
    override var id: Long = 0, 
    override var location: String = "", 
    var isbn: String 
) : Resource() 
+0

Che componente1 ??? – maaartinus

+0

Kotlin crea implicitamente metodi 'componentN()' che restituiscono il valore di N-esima proprietà. Vedi i documenti su [Multi-Declarations] (http://kotlinlang.org/docs/reference/multi-declarations.html) – Dmitry

+0

Per aprire le proprietà, puoi anche fare l'abstract delle risorse o usare il plug-in del compilatore. Kotlin è rigido nei confronti del principio aperto/chiuso. –

risposta

33

La verità è: classi di dati non giocare troppo bene con l'ereditarietà. Stiamo valutando la possibilità di vietare o limitare severamente l'ereditarietà delle classi di dati. Ad esempio, è noto che non è possibile implementare correttamente equals() in una gerarchia su classi non astratte.

Quindi, tutto ciò che posso offrire: non utilizzare l'ereditarietà con classi di dati.

+0

Hey Andrey, come funziona equals() mentre viene generato nelle classi di dati ora? Corrisponde solo se il tipo è esatto e tutti i campi comuni sono uguali o solo se i campi sono uguali? Sembra che, a causa del valore dell'ereditarietà delle classi per l'approssimazione dei tipi di dati algebrici, potrebbe valere la pena trovare una soluzione a questo problema. È interessante notare che una ricerca superficiale ha rivelato questa discussione sull'argomento di Martin Odersky: http://www.artima.com/lejava/articles/equality.html – orospakr

+1

Non credo che ci sia molto di una soluzione a questo problema. La mia opinione è che le classi di dati non debbano avere sottoclassi di dati. –

+1

e se avessimo un codice di libreria come un ORM e vogliamo estendere il suo modello per avere il nostro modello di dati persistente? –

18

Dichiarare le proprietà in super classe al di fuori del costruttore come astratte e sovrascriverle in sottoclasse.

abstract class Resource { 
    abstract var id: Long 
    abstract var location: String 
} 

data class Book (
    override var id: Long = 0, 
    override var location: String = "", 
    var isbn: String 
) : Resource() 
+1

questo sembra essere il più flessibile. Auspico vivamente che potremmo semplicemente avere classi di dati ereditate l'una dall'altra ... – Adam

+0

questo il modo migliore –