Sobes.tech
Middle

Czym są właściwości delegowane w Kotlin?

sobes.tech AI

Odpowiedź od AI

Właściwości delegowane to sposób delegowania logiki pobierania (get) i ustawiania (set) wartości właściwości do innego obiektu. Pozwala to na wyodrębnienie powtarzającego się kodu i uczynienie klas bardziej zwartych.

Główne komponenty:

  • Delegat: Obiekt implementujący interfejsy ReadOnlyProperty (dla val) lub ReadWriteProperty (dla var). Zawiera logikę dla getValue() i opcjonalnie setValue().
  • Operator by: Słowo kluczowe w Kotlinie używane do powiązania właściwości z jej delegatem.

Przykłady standardowych delegatów:

  • lazy: Inicjalizacja właściwości następuje tylko przy pierwszym dostępie.
    // Przykład delegata lazy
    val lazyValue: String by lazy {
        println("zainicjowano")
        "Hello"
    }
    
  • delegates.observable: Wykonuje akcję po każdej przypisaniu wartości do właściwości.
    // Przykład delegata observable
    var name: String by kotlin.properties.Delegates.observable("<brak nazwy>") {
        prop, old, new ->
        println("$old -> $new")
    }
    
  • delegates.vetoable: Pozwala przechwycić przypisanie i anulować je, jeśli warunek nie jest spełniony.
    // Przykład delegata vetoable
    var age: Int by kotlin.properties.Delegates.vetoable(0) {
        prop, old, new -> new >= 0
    }
    
  • Delegacja do innej właściwości: Można delegować właściwość do innej.
    // Przykład delegacji do innej właściwości
    var text: String = "Oryginalny"
    var delegatedText: String by ::text
    

Tworzenie własnych delegatów:

Należy zaimplementować interfejs ReadOnlyProperty lub ReadWriteProperty.

// Przykład własnego delegata ReadWriteProperty
import kotlin.reflect.KProperty

class ExampleDelegate {
    private var value: String = ""

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("$thisRef, dziękuję za delegowanie '${property.name}' do mnie!")
        return value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef, dziękuję za delegowanie '${property.name}' do mnie!")
        this.value = value
    }
}

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

Zalety:

  • Ponowne użycie logiki getter/setter.
  • Poprawa czytelności kodu.
  • Zmniejszenie boilerplate.
  • Czyste API do pracy z właściwościami.
Czym są właściwości delegowane w Kotlin? — Kotlin - sobes.tech