Sobes.tech
Middle

Qual è la caratteristica dei delegati delle proprietà?

sobes.tech AI

Risposta dell'AI

I delegati delle proprietà in Kotlin consentono di trasferire la logica di recupero e impostazione del valore di una proprietà a una classe ausiliaria chiamata delegato.

Caratteristiche:

  1. Comprensione di getValue e setValue: Per le proprietà accessibili in lettura (val), il delegato deve avere un metodo getValue. Per le proprietà accessibili in lettura e scrittura (var), il delegato deve avere sia getValue che setValue. Questi metodi prendono come parametri:

    • Un riferimento all'oggetto che contiene la proprietà (per i membri della classe).
    • Metadati della proprietà sotto forma di un oggetto KProperty.
  2. Delegati standard: Kotlin fornisce diversi delegati standard:

    • lazy: Per l'inizializzazione differita della proprietà.
    • observable: Per eseguire un'azione quando il valore della proprietà cambia.
    • vetoable: Per eseguire un'azione quando il valore della proprietà cambia, con la possibilità di annullare il cambiamento.
    • Delegati per le mappe: La proprietà può essere memorizzata in una Map.
  3. Delegati arbitrari: È possibile creare proprie classi delegato. La classe deve implementare le interfacce ReadOnlyProperty (per val) o ReadWriteProperty (per var).

Esempio di utilizzo di lazy:

// Il campo viene inizializzato solo al primo accesso
val lazyValue: String by lazy { 
    println("Calcolo del valore")
    "Hello"
}

Esempio di utilizzo di observable:

import kotlin.properties.Delegates

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

Esempio di delegato personalizzato:

import kotlin.reflect.KProperty

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, valore della proprietà '${property.name}'"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef, valore della proprietà '${property.name}' modificato in '$value'")
    }
}

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