Sobes.tech
Middle

Kas saak selgitada delegaadi tööpõhimõtet klassis Kotlin?

sobes.tech AI

Vastus AI-lt

Kotlinis on delegeerimis objekt, mis võtab enda kanda teatud ülesande täitmise või delegeerib meetodite väljakutsed teisele objektile.

Peamised kasutusstsenaariumid:

  1. Omaduste delegeerimine (Delegated Properties): Juhtimise üleandmine getteritele ja setteritele teisele objektile.

    • lazy: Omaduse väärtuse arvutamine esimesel juurdepääsul.
    • observable: Tegevuse sooritamine omaduse väärtuse muutmisel.
    • vetoable: Omaduse väärtuse muutmise keeld tingimuse alusel.
    class Example {
        // Arvutatakse ainult esimesel juurdepääsul
        val lazyValue: String by lazy {
            println("Arvutan!")
            "Tere"
        }
    
        // Kutsutakse iga muutuse korral
        var name: String by Delegates.observable("<nimi puudub>") { prop, old, new ->
            println("Nimi muutus $old-lt $new-le")
        }
    }
    
  2. Liideste delegeerimine (Class Delegation): Liidese realiseerimine meetodite väljakutsete suunamisega teisele objektile.

    interface Base {
        fun print()
    }
    
    class BaseImpl(val x: Int) : Base {
        override fun print() {
            println(x)
        }
    }
    
    // Rakendab Base, delegeerides väljakutsed BaseImpl-ile
    class Derived(b: Base) : Base by b
    
    fun main() {
        val b = BaseImpl(10)
        Derived(b).print() // Väljund: 10
    }
    
  3. Funktsioonide delegeerimine (Function Delegation): Kuigi otsest süntaksit funktsioonide delegeerimiseks pole, realiseeritakse see kontseptuaalselt koostöö ja teiste objektide meetodite väljakutsete kaudu.

Kuidas töötab omaduste delegeerimine:

Kotlini kompilaator genereerib abikoodi. Delegeeritud omaduse jaoks delegate-le genereerib kompilaator varjatud omaduse ja kutsub välja getValue ja setValue meetodid (muudetavate omaduste jaoks) delegate-i objektil, edastades vajaliku konteksti (klassinäide, omaduse metaandmed).

// Pseudo-kood näide, kuidas kompilaator töötleb: val p: String by delegate
/*
private val _p: Delegate<Any?, String> = delegate_initializer
val p: String
    get() = _p.getValue(this, ::p) // Kutsub getValue delegaadilt
*/

Delegeeriv objekti peab omama vastavaid meetodeid:

  • getValue(thisRef, property: KProperty<*>): T omadustele T. thisRef on klassi näide, property omaduse metaandmed.
  • setValue(thisRef, property: KProperty<*>, value: T) muudetavatele omadustele.

Eelised:

  • Koodi korduvkasutus: Üldine loogika (lazy initsialiseerimine, muudatuste jälgimine) kantakse üle eraldi delegaadile ja seda saab kasutada mitu korda.
  • Lugemise parandamine: Kood muutub väiksemaks, boilerplate-kood on peidetud delegaadi sisse.
  • Modularsus: Omaduste haldamise või liideste realiseerimise loogika eraldatakse põhiklassi loogikast.