Sobes.tech
Middle

Quelle est la particularité des délégués de propriétés?

sobes.tech IA

Réponse de l'IA

Les délégués de propriétés en Kotlin permettent de transférer la logique d'obtention et de définition de la valeur d'une propriété à une classe auxiliaire appelée délégué.

Caractéristiques :

  1. Compréhension de getValue et setValue : Pour les propriétés accessibles en lecture (val), le délégué doit avoir une méthode getValue. Pour les propriétés accessibles en lecture et écriture (var), le délégué doit avoir à la fois getValue et setValue. Ces méthodes prennent en paramètres :

    • Une référence à l'objet contenant la propriété (pour les membres de classe).
    • Les métadonnées de la propriété sous forme d'un objet KProperty.
  2. Délégués standard : Kotlin fournit plusieurs délégués standards :

    • lazy : pour l'initialisation différée de la propriété.
    • observable : pour effectuer une action lors du changement de la valeur de la propriété.
    • vetoable : pour effectuer une action lors du changement de la valeur de la propriété, avec la possibilité d'annuler le changement.
    • Délégués pour les maps : la propriété peut être stockée dans une Map.
  3. Délégués arbitraires : Il est possible de créer ses propres classes de délégués. La classe doit implémenter les interfaces ReadOnlyProperty (pour val) ou ReadWriteProperty (pour var).

Exemple d'utilisation de lazy :

// Le champ est initialisé uniquement lors du premier accès
val lazyValue: String by lazy { 
    println("Calcul de la valeur")
    "Hello"
}

Exemple d'utilisation de observable :

import kotlin.properties.Delegates

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

Exemple de délégué personnalisé :

import kotlin.reflect.KProperty

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

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef, la valeur de la propriété '${property.name}' a été modifiée à '$value'")
    }
}

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