2014-10-18 196 views
41

數據類似乎是Java中老式POJO的替代品。可以預見的是,這些類將允許繼承,但我沒有看到擴展數據類的方便途徑。我需要的是這樣的:在Kotlin中擴展數據類

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

上面的代碼因爲碰撞component1()方法失敗。僅在其中一個類中留下data註解也不能完成這項工作。

也許還有另外一個習語來擴展數據類嗎?

UPD:我可能僅註釋子子類,但data註釋只處理在構造函數中聲明的屬性。也就是說,我必須聲明所有父母的特性open和覆蓋他們,這是醜陋:

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

什麼組件1 ??? – maaartinus 2014-10-19 01:44:38

+0

Kotlin隱式創建返回第N個屬性值的方法'componentN()'。請參閱[Multi-Declarations]上的文檔(http://kotlinlang.org/docs/reference/multi-declarations.html) – Dmitry 2014-10-20 09:27:24

+0

要打開屬性,還可以使用Resource abstract或使用編譯器插件。 Kotlin對開放/封閉原則是嚴格的。 – 2017-11-06 08:12:03

回答

33

事實是:數據類不繼承發揮得太好。我們正在考慮禁止或嚴格限制數據類的繼承。例如,衆所周知,無法在非抽象類的層次結構中正確實施equals()

所以,我可以提供:不要對數據類使用繼承。

+0

Hey Andrey, equals()在數據類上生成時如何工作?如果類型是精確的並且所有常用字段相等,或只有字段相等,它才匹配嗎? 看起來好像,由於用於近似代數數據類型的類繼承的價值,可能值得提出解決此問題的解決方案。有趣的是,粗略的搜索揭示了Martin Odersky關於這個話題的討論:http://www.artima.com/lejava/articles/equality.html – orospakr 2015-03-29 04:19:05

+1

我不認爲這個問題有很多解決方案。目前爲止,我的觀點是數據類別一定不能有數據子類。 – 2015-03-30 10:01:07

+1

如果我們有一個庫代碼(比如某些ORM),並且我們想要擴展它的模型以獲得持久數據模型,該怎麼辦? – 2015-12-12 14:36:31

18

在構造函數之外的超類中聲明屬性爲abstract,並在子類中覆蓋它們。

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

這似乎是最靈活的。我非常希望我們可以讓數據類繼承對方,儘管... – Adam 2017-09-01 00:26:53

+0

這是最好的方法 – 2017-10-19 11:20:22