Sobes.tech
Middle

Em que consiste a característica dos delegados de propriedades?

sobes.tech IA

Resposta da IA

Os delegados de propriedades em Kotlin permitem transferir a lógica de obtenção e definição do valor de uma propriedade para uma classe auxiliar chamada delegado.

Características:

  1. Compreensão de getValue e setValue: Para propriedades acessíveis para leitura (val), o delegado deve ter um método getValue. Para propriedades acessíveis para leitura e escrita (var), o delegado deve ter tanto getValue quanto setValue. Esses métodos recebem como parâmetros:

    • Uma referência ao objeto que contém a propriedade (para membros de classe).
    • Metadados da propriedade na forma de um objeto KProperty.
  2. Delegados padrão: Kotlin vem com vários delegados padrão:

    • lazy: Para inicialização diferida da propriedade.
    • observable: Para realizar alguma ação ao alterar o valor da propriedade.
    • vetoable: Para realizar alguma ação ao alterar o valor da propriedade, com a possibilidade de cancelar a alteração.
    • Delegados para mapas: A propriedade pode ser armazenada em um Map.
  3. Delegados arbitrários: Pode-se criar classes próprias de delegados. A classe deve implementar as interfaces ReadOnlyProperty (para val) ou ReadWriteProperty (para var).

Exemplo de uso de lazy:

// O campo é inicializado apenas na primeira acesso
val lazyValue: String by lazy { 
    println("Calculando valor")
    "Hello"
}

Exemplo de uso de observable:

import kotlin.properties.Delegates

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

Exemplo de delegado personalizado:

import kotlin.reflect.KProperty

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, valor da propriedade '${property.name}'"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef, valor da propriedade '${property.name}' alterado para '$value'")
    }
}

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