Poți explica principiul de funcționare al unui delegat într-o clasă în Kotlin?
sobes.tech AI
Răspuns de la AI
Un delegat în Kotlin este un obiect care preia executarea unei sarcini specifice sau delegă apelurile de metode către un alt obiect.
Scenarii principale de utilizare:
-
Delegarea proprietăților: Transferarea controlului asupra getter-urilor și setter-urilor unei proprietăți către un alt obiect.
lazy: Calcularea valorii proprietății la prima accesare.observable: Executarea unei acțiuni atunci când valoarea proprietății se schimbă.vetoable: Interzicerea schimbării valorii proprietății pe baza unei condiții.
class Example { // Calculat doar la prima accesare val lazyValue: String by lazy { println("Calcul!") "Salut" } // Este apelat la fiecare schimbare de valoare var name: String by Delegates.observable("<fără nume>") { prop, old, new -> println("Numele s-a schimbat de la $old la $new") } } -
Delegarea interfețelor: Implementarea unei interfețe prin redirecționarea apelurilor de metode către un alt obiect.
interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() { println(x) } } // Implementă Base, delegând apelurile către BaseImpl class Derived(b: Base) : Base by b fun main() { val b = BaseImpl(10) Derived(b).print() // Va afișa 10 } -
Delegarea funcțiilor: Deși nu există o sintaxă explicită pentru delegarea funcțiilor individuale, acest lucru se realizează conceptual prin compoziție și apeluri de metode ale altor obiecte.
Cum funcționează delegarea proprietăților:
Compilatorul Kotlin generează cod auxiliar. Pentru o proprietate delegată unui obiect delegate, compilatorul generează o proprietate ascunsă și apelează metodele getValue și setValue (pentru proprietățile modificabile) pe obiectul delegate, transmitând contextul necesar (instanța clasei, metadatele proprietății).
// Exemplu de pseudocod, cum procesează compilatorul: val p: String by delegate
/*
private val _p: Delegate<Any?, String> = delegate_initializer
val p: String
get() = _p.getValue(this, ::p) // Apelul la getValue pe delegat
*/
Obiectul delegat trebuie să aibă metodele corespunzătoare:
getValue(thisRef, property: KProperty<*>): Tpentru proprietate de tipT.thisRefeste instanța clasei,propertysunt metadatele proprietății.setValue(thisRef, property: KProperty<*>, value: T)pentru proprietate modificabilă.
Avantajele utilizării delegatelor:
- Reutilizarea codului: Logica comună (inițializarea leneșă, observarea schimbărilor) este extrasă într-un delegat separat și reutilizată.
- Îmbunătățirea lizibilității: Codul devine mai puțin voluminos, boilerplate-ul este ascuns în interiorul delegatului.
- Modularitate: Logica de gestionare a proprietăților sau implementarea interfețelor se separă de logica principală a clasei.