java - open - method kotlin
Delegación de Kotlin a expresión en lugar de referencia fija (2)
Puede agregar un nivel de direccionamiento indirecto:
class Holder(var impl: Spec) : Spec {
override fun sayHello() = impl.sayHello()
}
class Derived(target: Spec,
private val holder: Holder = Holder(target)) : Spec by holder {
fun changeTarget(newTarget: Spec) {
holder.impl = newTarget
}
}
Lamentablemente, el holder
debe ser un parámetro de constructor para poder usarlo con la construcción de delegación (como en el caso de Kotlin v1.0), por lo que complica el constructor principal.
Supongamos que tengo una especificación muy compleja definida como una interfaz:
interface Spec {
fun sayHello()
}
Y una implementación estándar:
class Impl(private val msg: String) : Spec {
override fun sayHello() {
println(msg)
}
}
Supongamos ahora que quiero crear una clase que implemente esta especificación y delegue en una implementación, pero el objeto delegado exacto se puede modificar a lo largo de la vida del objeto. Aquí hay un ejemplo:
class Derived(var target: Spec) : Spec by target
El problema con el ejemplo anterior es que el target
argumento constructor se establece como el objeto delegado cuando se llama al constructor. La clase accede directamente al delegado en lugar de realizar un acceso a la propiedad. (Esto ha sido confirmado mirando el bytecode producido por Kotlin).
Por lo tanto, incluso si el target
la propiedad se modifica después de que se construye la clase, el delegado no cambia.
¿Alguien puede proporcionar un método para realizar esta delegación en Kotlin sin tener que escribir todos los métodos?
Una solución ideal también permitiría delegar en algo tan general como una lambda u otra expresión que sería evaluada y utilizada como delegado cada vez que el delegado se necesita durante toda la vida del objeto.
En este momento no hay forma de hacer eso. Ver el número KT-5870 de Kotlin
Currenlty Kotlin evalúa expresión para delegado en el inicializador de clase