具有主构造函数的java继承类
我有一个父类,如下所示
interface ITask { }
open class Task(val targetServer: Server) : ITask { }
然后有一个子级继承它并重写主构造函数,如下所示
data class FileTask(val sourceServer: Server, targetServer: Server) : Task(targetServer = targetServer) {
}
这是在eclipse中抛出一个编译错误
Data class primary constructor must have only property (val / var) parameters
从类头中删除data
关键字将消除错误,但我不明白为什么
保留data
关键字并将var
添加到targetServer
会产生另一个错误
'targetServer' hides member of supertype 'Task' and needs 'override' modifier
将override
添加到targetServer
将override var targetServer: Server
引发另一个错误
'targetServer' in 'Task' is final and cannot be overridden
我需要一些帮助来理解这些错误
# 1 楼答案
初始错误是因为数据类在其主构造函数中不能有
val
或var
属性以外的参数。删除data
关键字将解除此限制有人提到,数据类通常不能很好地处理继承。它们应该被用作简单的数据传输对象,并不真正适合参与层次结构,因为很难理解在生成的方法的实现中要考虑哪些属性。你最好不要在这里使用它们
关于数据类和继承的更多信息,here是在Kotlin 1.1中实现的建议
为了回到具体的问题,如果您真的必须使这个类成为数据类,您可以将基类中的属性标记为
open
,然后在FileTask
中重写它,如下所示:这基本上隐藏了在
Task
中声明的属性,并且总是访问FileTask
中的属性我不知道您对类的确切要求是什么,但有一件事可以做,那就是将
Task
及其targetServer
属性抽象化,比如:这样,在基类中就不会有不必要的属性(和backing字段),并且在从
Task
继承的所有类中都必须有targetServer
属性。您还可以更进一步,将属性也放在ITask
接口中# 2 楼答案
我知道这是一篇非常古老的帖子,但我也在为同样的问题而挣扎,而将我的超类抽象并不是一个解决方案。 您只需执行以下操作:
改变这个
to(请注意,我已使targetServer变量打开)