2014-10-18 201 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