Llamar al constructor de super class en Kotlin, Super no es una expresión

Tengo dos classs Entity y Account como

 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; } } 

y

 data class Account( var name: String? = null, var accountFlags: Int? = null ) : Entity() { constructor(entity: Entity) : this() { super(entity) } } 

Lo cual me da el error

Super no es una expresión, solo se puede usar en el lado izquierdo de un punto '.'

¿Por qué no puedo hacer eso?

Lo siguiente pasará el error de compilation, pero no estoy seguro de si es correcto.

  constructor(entity: Entity) : this() { super.fromEntity(entity) } 

Tienes un par de problemas en tu código.

Primero, esta es la syntax correcta, para llamar a un súper constructor desde un constructor secundario:

 constructor(entity: Entity) : super(entity) 

En segundo lugar, no puede llamar a un superconstructor de un constructor secundario si su class tiene un constructor primario (que su class).

Solución 1

 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) } 

Aquí, el constructor de copy está en la class secundaria que simplemente delega en el constructor primario.

Solución 2

 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 } } 

Aquí solo estoy usando constructores secundarios en la class secundaria, lo que me permite delegarlos en super constructores individuales. Observe cómo el código es bastante largo.

Solución 3 (más idiomática)

 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() 

Aquí omití los constructores de copy e hice abstractas las properties para que la class hija tenga todas las properties. También hice que la class infantil fuera una data class . Si necesita clonar la class, simplemente puede llamar a account.copy() .

Utilice esta super<Entity>.fromEntity(entity) para llamar a los methods de super<Entity>.fromEntity(entity) .

Como dice la documentation:

En Kotlin, la inheritance de implementación está regulada por la siguiente regla: si una class henetworkinga muchas implementaciones del mismo miembro de sus superclasss inmediatas, debe anular a este miembro y proporcionar su propia implementación (tal vez, utilizando una de las henetworkingadas). Para denotar el supertipo del que se toma la implementación henetworkingada, usamos supercalificado por el nombre del supertipo entre corchetes angulares, por ejemplo, super.

 constructor(entity: Entity) : this() { super<Entity>.fromEntity(entity) } 

Para saber más leer Reglas Anuladas

  • java.lang.NoClassDefFoundError en Kotlin
  • No se esperan arguments de tipo para la diversión findViewById (p0: Int): Ver
  • ¿Por qué no puedo get los valores de mi file JSON?
  • Clase de datos Igualdad en Kotlin
  • Formateo de comentarios de Kotlin en IntelliJ / Android Studio
  • Error de Kotlin: Dagger no admite inyección en campos privados
  • FIRESTORE datos persistentes
  • ¿Cuál es la forma recomendada de deserializar un documento de Firestre que contiene una matriz?
  • En Kotlin, ¿cómo agrego methods de extensión a otra class, pero solo visibles en un context determinado?
  • Interfaces de Kotlin exportando a properties perdidas de Javascript
  • Sitio de Android: select la consulta con LIKE