Henetworkingar class con constructor primario

Tengo una class para padres como siguiente,

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

Luego hay un niño que lo henetworkinga y anula el constructor principal de la siguiente manera:

 data class FileTask(val sourceServer: Server, targetServer: Server) : Task(targetServer = targetServer) { } 

Esto arroja un error de compilation en eclipse como

El constructor primario de class de datos debe tener solo parameters de propiedad (val / var)

Eliminar la palabra key de data del encabezado de class matará el error, pero no entiendo por qué.

Mantener la palabra key data y agregar var al targetServer le da otro error

'targetServer' oculta el miembro del supertipo 'Tarea' y necesita el modificador 'anular'

Agregar override al targetServer para override var targetServer: Server arroja otro error

'targetServer' en 'Tarea' es final y no se puede anular

Necesito ayuda para entender estos errores.

Solutions Collecting From Web of "Henetworkingar class con constructor primario"

El error inicial se debe a que una class de datos no puede tener parameters en su constructor primario distintos de las properties val o var . Al eliminar la palabra key de data levanta esta restricción.

Se ha mencionado que las classs de datos generalmente no funcionan bien con la inheritance. Se supone que deben usarse como objects simples de transferencia de datos, y no son realmente adecuados para participar en jerarquías, porque resulta difícil comprender qué properties se tendrán en count en las implementaciones de los methods generados. Su mejor opción podría ser no usarlas en absoluto aquí.

Para get más información sobre las classs de datos y la inheritance, esta es la propuesta que se implementó en Kotlin 1.1.


Para volver al problema específico, si realmente tiene que hacer de esta class una class de datos, puede marcar la propiedad en la class base como open y luego FileTask en FileTask , de esta forma:

 open class Task(open val targetServer: Server) : ITask data class FileTask(val sourceServer: Server, override val targetServer: Server): Task(targetServer = targetServer) 

Esto básicamente oculta la propiedad declarada en Task , y siempre accede a la propiedad en FileTask en FileTask lugar.

No sé cuáles son sus requisitos exactos para sus classs, pero una cosa que podría hacer para limpiar esto y hacerlo un poco más agradable sería hacer que la Task y su propiedad targetServer abstractas, así:

 abstract class Task : ITask { abstract val targetServer: Server } data class FileTask(val sourceServer: Server, override val targetServer: Server) : Task() 

De esta forma, no tendría la propiedad innecesaria (y el campo de respaldo) en la class base, y estaría forzado a tener una propiedad targetServer en todas las classs targetServer de Task . También puede llevar esto un paso más allá y poner la propiedad en la interfaz de ITask también.

 interface ITask { val targetServer: Server }