使用主构造函数继承类

时间:2017-05-23 08:16:07

标签: java kotlin

我有一个如下的父类,

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'是最终的,无法覆盖

我需要一些帮助来理解这些错误。

2 个答案:

答案 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 { }