在Kotlin中调用超级类构造函数,超级不是表达式
我有两个类在Kotlin中调用超级类构造函数,超级不是表达式,kotlin,Kotlin,我有两个类实体和账户作为 abstract class Entity( var id: String? = null, var created: Date? = Date()) { constructor(entity: Entity?) : this() { fromEntity(entity) } fun fromEntity(entity: Entity?): Entity { id = entity?.id
实体
和账户
作为
abstract class Entity(
var id: String? = null,
var created: Date? = Date()) {
constructor(entity: Entity?) : this() {
fromEntity(entity)
}
fun fromEntity(entity: Entity?): Entity {
id = entity?.id
created = entity?.created
return this;
}
}
及
这给了我一个错误
Super不是一个表达式,它只能用于
一个“点”
为什么我不能那样做
下面将传递编译错误,但我不确定它是否正确
constructor(entity: Entity) : this() {
super.fromEntity(entity)
}
使用此super.fromtentity(entity)
调用超类方法
正如文件所说:
在Kotlin中,实现继承受以下规则的约束:如果一个类从其直接超类继承同一成员的多个实现,它必须重写该成员并提供自己的实现(可能使用其中一个继承的实现)。为了表示从中获取继承实现的超类型,我们使用尖括号中由超类型名称限定的super,例如super
构造函数(实体:实体):this(){
super.fromEntity(实体)
}
要了解更多信息,请阅读代码中的几个问题 首先,这是从辅助构造函数调用超级构造函数的正确语法:
constructor(entity: Entity) : super(entity)
其次,如果您的类具有主构造函数(您的类具有主构造函数),则不能从次构造函数调用超级构造函数
解决方案1
这里,复制构造函数位于子类中,该子类仅委托给主构造函数
解决方案2
这里我只在子类中使用二级构造函数,它允许我将它们委托给单个超级构造函数。注意代码是多么的长
解决方案3(最惯用)
在这里,我省略了复制构造函数,并将属性抽象,以便子类具有所有属性。我还创建了子类a
数据类
。如果需要克隆类,只需调用account.copy()
另一个选项是创建伴生对象并提供工厂方法,例如
class Account constructor(
var name: String? = null,
var accountFlags: Int? = null,
id: String?,
created: Date?
) : Entity(id, created) {
companion object {
fun fromEntity(entity: Entity): Account {
return Account(null, null, entity.id, entity.created)
}
}
}
您还可以将主构造函数向下移动到类中,如下所示:
data class Account: Entity {
constructor(): super()
constructor(var name: String? = null, var accountFlags: Int? = null): super()
constructor(entity: Entity) : super(entity)
}
这样做的好处是,编译器不需要您的辅助构造函数调用主构造函数。您可以在此处找到如何调用超级构造函数的规则:。简而言之,如果超类有一个主构造函数,您必须从基类的所有构造函数中调用它。
构造函数(实体:实体):super(实体)
@zsmb13您能分享一些代码吗?@Miha_x64我已经试过了,它给出了主构造函数调用,这是预期的。
。谢谢回复。我知道表示超类型。但这实际上是一个解决办法。我想使用超级构造函数。谢谢。我已经尝试了语法构造函数(entity:entity):super(entity)
,但它给出了相同的错误super不是表达式…
我没有尝试您建议的代码,但我有一个问题。如果我必须在每个子类中重新定义相同的字段,那么拥有父类有什么好处?正如我在回答中所说,“如果你的类有一个主构造函数,你不能从二级构造函数调用超级构造函数”。考虑到您的担心,子类没有相同的字段。它有构造函数参数,它传递给定义属性的超类。如果我从子类中删除了主构造函数,我可以调用父类构造函数吗?你能用示例代码更新你的答案吗?@amreladaw我已经用另外两个解决方案更新了我的答案。谢谢你的更新。我将投票赞成这些努力。我仍然对解决方案有很多顾虑。它们需要丢失数据
性质,并且仍然需要在子项中添加父项字段,我可以通过完全删除父项来避免这种情况。我仍然看到我的问题有更少的编码。
abstract class Entity(
var id: String,
var created: Date
)
class Account(
var name: String,
var accountFlags: Int,
id: String,
created: Date
) : Entity(id, created) {
constructor(account: Account) : this(account.name, account.accountFlags, account.id, account.created)
}
abstract class Entity(
var id: String,
var created: Date
) {
constructor(entity: Entity) : this(entity.id, entity.created)
}
class Account : Entity {
var name: String
var accountFlags: Int
constructor(name: String, accountFlags: Int, id: String, created: Date) : super(id, created) {
this.name = name
this.accountFlags = accountFlags
}
constructor(account: Account) : super(account) {
this.name = account.name
this.accountFlags = account.accountFlags
}
}
abstract class Entity {
abstract var id: String
abstract var created: Date
}
data class Account(
var name: String,
var accountFlags: Int,
override var id: String,
override var created: Date
) : Entity()
class Account constructor(
var name: String? = null,
var accountFlags: Int? = null,
id: String?,
created: Date?
) : Entity(id, created) {
companion object {
fun fromEntity(entity: Entity): Account {
return Account(null, null, entity.id, entity.created)
}
}
}
data class Account: Entity {
constructor(): super()
constructor(var name: String? = null, var accountFlags: Int? = null): super()
constructor(entity: Entity) : super(entity)
}