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

  • El widget PlaceAutocomplete no funciona en Android 4.1
  • ¿Cómo funcionan las funciones de extensión de Kotlin?
  • No tiene administrador activo ... - bloqueando una pantalla en Android
  • Objeto literal de Kotlin que implementa una interfaz genérica de autorreference cardada
  • Prueba JUnit en Kotlin
  • AspectJ Problemas del comstackdor con la delegación de kotlin en la jerarquía de types
  • Kotlin: ¿funciones de extensión y types de plataforma?
  • Los files de Kotlin + Dagger 2: Dagger * no generarán
  • Usando @JvmOverloads de Kotlin con el patrón Fragment.newInstance () de Android
  • function maxBy binaria estándar
  • Cómo clonar o copyr una list en kotlin