J'ai deux classes Entity
et Account
comme
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;
}
}
et
data class Account(
var name: String? = null,
var accountFlags: Int? = null
) : Entity() {
constructor(entity: Entity) : this() {
super(entity)
}
}
Ce qui me donne l'erreur
Super n'est pas une expression, il ne peut être utilisé que dans la partie gauche de un point '.'
Pourquoi je ne peux pas faire ça?
Ce qui suit passera l'erreur de compilation, mais je ne suis pas sûr qu'elle soit correcte.
constructor(entity: Entity) : this() {
super.fromEntity(entity)
}
Vous avez quelques problèmes dans votre code.
Tout d’abord, c’est la syntaxe correcte pour appeler un super constructeur à partir d’un constructeur secondaire:
constructor(entity: Entity) : super(entity)
Deuxièmement, vous ne pouvez pas appeler un super constructeur depuis un constructeur secondary si votre classe a un constructeur primary (ce que votre classe possède).
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)
}
Ici, le constructeur de copie est dans la classe enfant qui délègue simplement le constructeur principal.
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
}
}
Ici, je n'utilise que des constructeurs secondaires dans la classe enfant, ce qui me permet de les déléguer à des super constructeurs individuels. Remarquez comme le code est assez long.
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()
Ici, j'ai omis les constructeurs de copie et rendu les propriétés abstraites afin que la classe enfant possède toutes les propriétés. J'ai également fait de la classe enfant un data class
. Si vous avez besoin de cloner la classe, vous pouvez simplement appeler account.copy()
.
Utilisez cette super<Entity>.fromEntity(entity)
pour appeler des méthodes de super classe.
Comme le dit la documentation:
En Kotlin, l'héritage d'implémentation est régi par la règle suivante: si une classe hérite de plusieurs implémentations du même membre de ses superclasses immédiates, elle doit remplacer ce membre et fournir sa propre implémentation (peut-être en utilisant l'une des héritées). Pour désigner le supertype dont est issue l'implémentation héritée, nous utilisons super qualifié par le nom du supertype entre crochets angulaires, par ex. super.
constructor(entity: Entity) : this() {
super<Entity>.fromEntity(entity)
}
Pour en savoir plus lire Règles primordiales