繁体   English   中英

使用主构造函数继承类

[英]Inheriting class with primary constructor

我有一个父类如下,

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'隐藏超类'Task'的成员,需要'override'修饰符

override添加到targetServeroverride var targetServer: Server会引发另一个错误

“任务”中的“targetServer”是最终版,无法覆盖

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

初始错误是因为除了valvar属性之外,数据类的主构造函数中不能包含参数。 删除data关键字会解除此限制。

有人提到数据类通常不能很好地继承。 它们应该被用作简单的数据传输对象,并且不适合参与层次结构,因为很难理解在生成的方法的实现中将考虑哪些属性。 你最好的选择可能就是不要在这里使用它们。

欲了解更多有关数据类和继承, 这里是在科特林1.1实施的建议。


要回到特定问题,如果你真的必须使这个类成为一个数据类,你可以将基类中的属性标记为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()

这样,您就不会在基类中拥有不必要的属性(和支持字段),并且您将被迫在从Task继承的所有类中拥有targetServer属性。 您还可以更进一步,并将属性放在ITask界面中。

interface ITask {
    val targetServer: Server
}

我知道这是一个非常古老的帖子,但我正在努力解决同样的问题并且使我的超类抽象不是一个解决方案。 您只需要执行以下操作:

改变这一点

open class Task(val targetServer: Server) : ITask { }

to(请注意,我已经打开了targetServer变量)

open class Task(open val targetServer: Server) : ITask { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM