我有一个如下的父类,
interface ITask { }
open class Task(val targetServer: Server) : ITask { }
然后有一个孩子继承它并覆盖主要构造函数,如下所示,
data class FileTask(val sourceServer: Server, targetServer: Server) : Task(targetServer = targetServer) {
}
这会在eclipse中抛出编译错误
数据类主构造函数必须只有property(val / var)参数
从类标题中删除data
关键字会导致错误,但我不明白为什么。
保留data
关键字并将var
添加到targetServer
会产生另一个错误
'targetServer'隐藏超类型'任务'的成员,需要'覆盖'修饰符
将override
添加到targetServer
以使override var targetServer: Server
引发其他错误
'任务'中的'targetServer'是最终的,无法覆盖
我需要一些帮助来理解这些错误。
答案 0 :(得分:11)
初始错误是因为数据类在其主要构造函数中不具有$htngdata = mysqli_num_rows($result);
或val
属性的参数。删除var
关键字会解除此限制。
有人提到数据类通常不能很好地继承。它们应该被用作简单的数据传输对象,并且不适合参与层次结构,因为很难理解在生成的方法的实现中将考虑哪些属性。你最好的选择可能就是不要在这里使用它们。
有关数据类和继承的更多信息,here是在Kotlin 1.1中实现的提案。
要回到特定问题,如果您真的必须将此类设为数据类,则可以将基类中的属性标记为data
,然后在open
中覆盖它,就像这样:
FileTask
这基本上隐藏了open class Task(open val targetServer: Server) : ITask
data class FileTask(val sourceServer: Server, override val targetServer: Server): Task(targetServer = targetServer)
中声明的属性,并始终访问Task
中的属性。
我不知道你对课程的确切要求是什么,但你可以做的一件事就是让FileTask
及其Task
更清楚。属性摘要,如:
targetServer
这样你就不会在基类中拥有不必要的属性(和支持字段),并且你必须在从{继承的所有类中强制拥有abstract class Task : ITask {
abstract val targetServer: Server
}
data class FileTask(val sourceServer: Server, override val targetServer: Server) : Task()
属性。 {1}}。您还可以更进一步,并将属性放在targetServer
界面中。
Task
答案 1 :(得分:0)
我知道这是一个非常古老的帖子,但我正在努力解决同样的问题并且使我的超类抽象不是一个解决方案。 您只需要执行以下操作:
更改此
open class Task(val targetServer: Server) : ITask { }
to(请注意,我已经打开了targetServer变量)
open class Task(open val targetServer: Server) : ITask { }