Delegación de class parcial en Kotlin

¿Cómo puedo delegar parcialmente los methods / campos en Kotlin?

Para ser específico: aquí estoy tratando de henetworkingar el User class de la interfaz TraitA e implementar el campo marked: Boolean en el contenedor StateA . Eso limpiaría la implementación del User , porque marked es solo un campo de estado. Tenga en count que TraitA no puede ser una class porque quiero usar varias de estas interfaces: User() : TraitA by StateA, TraitB by StateB, ..

 /* does not compile (Kotlin M12) */ interface TraitA { var marked: Boolean fun doStaffWithMarked() // must be overridable } class StateA() : TraitA { override var marked = false } class User() : TraitA by StateA(){ override fum doStaffWithMarked() { //...all fancy logic here... } } 

La alternativa es implementar todo en un solo lugar:

 class User() : TraitA{ override var marked = false // ugly code override fum doStaffWithMarked() { //... } } 

¿Hay alguna forma / patrón que resuelva ese problema con un código tan pequeño como sea posible? La generación de código / bytecode no es una opción para mí.

ACTUALIZAR

No estaba muy claro al respecto, pero tenga en count que doStaffWithMarked() es único para cada User .

Así que puedo sugerir una solución "medio mala" con aserciones en time de ejecución:

 interface TraitA { var marked: Boolean /* must be overridden */ fun doStaffWithMarked() = throw UnsupportedOperationException() } class StateA() : TraitA { override var marked = false } class User() : TraitA by StateA() { override fum doStaffWithMarked() { //...all fancy logic here... } } 

La pregunta sigue abierta, ya que una buena solución verificaría que doStaffWithMarked() en time de compilation.

Divida TraitA en dos interfaces, luego delegue el uno e implemente el otro:

 interface TraitA { var marked: Boolean } interface TraitAPlus : TraitA { fun isMarked(): Boolean } class StateA() : TraitA { override var marked = false } class User() : TraitA by StateA(), TraitAPlus { override fun isMarked(): Boolean { return marked } } 

Aquí hay una versión que simplemente henetworkinga de StateA lugar de delegar, pero eso no es muy agradable:

 interface TraitA { var marked: Boolean fun isMarked(): Boolean } abstract class StateA() : TraitA { override var marked = false } class User() : TraitA, StateA() { override fun isMarked(): Boolean { return marked } } 

Y aquí hay un enfoque algo inusual en el que delego TraitA a una instancia anónima de StateA

 class User() : TraitA by object : StateA() { override fun isMarked(): Boolean { return marked } } { } 

Sin embargo, para ser sincero, preferiría replantear el layout de la jerarquía de classs. En particular, puede poner implementaciones de methods en interfaces (pero no en valores de propiedad), de modo que si isMarked() solo depende del marked , puede poner la implementación directamente en TraitA . Su código se convierte en:

 interface TraitA { var marked: Boolean fun isMarked(): Boolean { return marked } } class StateA() : TraitA { override var marked = false } class User() : TraitA by StateA() { } 

Editar: respuesta separada: https://stackoverflow.com/a/30914383/615306

  • Kotlin - generate toString () para una class que no sea de datos
  • Mapa de Kotlin: ¿por qué no hay paraHashMap ()?
  • Llame al object Kotlin con la delegación de class de Java como método estático
  • Kotlin y @Transient
  • kotlin para anular los types de protobuf a String
  • Kotlin cuando con valores múltiples no funciona cuando el valor es una vista de Android
  • No se pueden agregar los fragments usando la function de Extensión de Kotlin
  • ¿Cuáles son los beneficios de escribir código JavaScript usando Kotlin?
  • ¿Por qué mi compilation Kotlin falla utilizando Kotlin-Maven-Plugin?
  • Sintaxis de quilates en las interfaces de Kotlin
  • Permisosdispatcher y múltiples @ NeedsPermission con kotlin