Sobes.tech
Middle

Vai vari izskaidrot delegāta darbības principu klasē Kotlin?

sobes.tech AI

Atbilde no AI

Kotlin delegāts ir objekts, kas uzņemas noteikta uzdevuma izpildi vai deleģē metožu izsaukšanu citam objektam.

Galvenie lietošanas scenāriji:

  1. Īpašību deleģēšana (Delegated Properties): Pārraide pārvaldības pārvaldība ar geteriem un seteriem citam objektam.

    • lazy: Īpašības vērtības aprēķins pirmajā piekļuvē.
    • observable: Darbības izpilde īpašības vērtības maiņas laikā.
    • vetoable: Vērtības maiņas aizliegums atkarībā no nosacījuma.
    class Example {
        // Tiek aprēķināts tikai pirmajā piekļuvē
        val lazyValue: String by lazy {
            println("Aprēķinu!")
            "Sveiki"
        }
    
        // Izsauc katru reizi, kad mainās vērtība
        var name: String by Delegates.observable("<nav vārda>") { prop, old, new ->
            println("Vārds mainījās no $old uz $new")
        }
    }
    
  2. Interfeisu deleģēšana (Class Delegation): Interfeisa realizācija, novirzot metoņu izsaukumus citam objektam.

    interface Base {
        fun print()
    }
    
    class BaseImpl(val x: Int) : Base {
        override fun print() {
            println(x)
        }
    }
    
    // Realizē Base, deleģējot izsaukumus BaseImpl
    class Derived(b: Base) : Base by b
    
    fun main() {
        val b = BaseImpl(10)
        Derived(b).print() // Izdrukās 10
    }
    
  3. Funkciju deleģēšana (Function Delegation): Lai arī nav tiešas sintakses funkciju deleģēšanai, tas konceptuāli tiek īstenots caur kompozīciju un metožu izsaukšanu citam objektam.

Kā darbojas īpašību deleģēšana:

Kotlin kompilators ģenerē palīgkodu. Attiecīgajai īpašībai, kas deleģēta delegate objektam, kompilators ģenerē slēptu īpašību un izsauc getValue un setValue metodes (maināmām īpašībām) delegate objektā, nododot nepieciešamo kontekstu (klases eksemplāru, īpašības metadatus).

// Pseido-koda piemērs, kā kompilators apstrādā: val p: String by delegate
/*
private val _p: Delegate<Any?, String> = delegate_initializer
val p: String
    get() = _p.getValue(this, ::p) // Izsauc `getValue` uz delegāta
*/

Delegējošais objekts ir jābūt ar atbilstošiem metodēm:

  • getValue(thisRef, property: KProperty<*>): T īpašībām T. thisRef ir klases eksemplārs, property — īpašības metadati.
  • setValue(thisRef, property: KProperty<*>, value: T) maināmām īpašībām.

Priekšrocības:

  • Koda atkārtota lietošana: Vispārīgā loģika (lazy inicializācija, izmaiņu uzraudzība) tiek pārvietota uz atsevišķu delegātu un tiek izmantota vairākas reizes.
  • Lasāmības uzlabošana: Kods kļūst mazāks, boilerplate kods ir slēpts iekšā delegātā.
  • Modularitāte: Logika īpašību pārvaldībā vai interfeisu realizācijā tiek atdalīta no galvenās klases loģikas.