Sobes.tech
Middle

¿En qué consiste la característica de los delegados de propiedades?

sobes.tech AI

Respuesta de la IA

Los delegados de propiedades en Kotlin permiten transferir la lógica de obtención y establecimiento del valor de una propiedad a una clase auxiliar llamada delegado.

Características:

  1. Comprensión de getValue y setValue: Para propiedades accesibles para lectura (val), el delegado debe tener un método getValue. Para propiedades accesibles para lectura y escritura (var), el delegado debe tener tanto getValue como setValue. Estos métodos toman como parámetros:

    • Una referencia al objeto que contiene la propiedad (para miembros de clase).
    • Metadatos de la propiedad en forma de un objeto KProperty.
  2. Delegados estándar: Kotlin viene con varios delegados estándar:

    • lazy: Para inicialización diferida de la propiedad.
    • observable: Para realizar alguna acción al cambiar el valor de la propiedad.
    • vetoable: Para realizar alguna acción al cambiar el valor de la propiedad, con la posibilidad de cancelar el cambio.
    • Delegados para mapas: La propiedad puede almacenarse en un Map.
  3. Delegados arbitrarios: Se pueden crear clases propias de delegados. La clase debe implementar las interfaces ReadOnlyProperty (para val) o ReadWriteProperty (para var).

Ejemplo de uso de lazy:

// El campo se inicializa solo en el primer acceso
val lazyValue: String by lazy { 
    println("Calculando valor")
    "Hello"
}

Ejemplo de uso de observable:

import kotlin.properties.Delegates

var name: String by Delegates.observable("<sin nombre>") {
    property, oldValue, newValue ->
    println("$oldValue -> $newValue")
}

Ejemplo de delegado personalizado:

import kotlin.reflect.KProperty

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, valor de la propiedad '${property.name}'"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef, el valor de la propiedad '${property.name}' ha sido cambiado a '$value'")
    }
}

class Example {
    var p: String by Delegate()
}