Перейти до вмісту

Освоюємо Kotlin/Делегування

Матеріал з Вікіпідручника


Делегування (delegation) - це механізм надання додаткової функціональності об'єкту без механізму успадкування в Kotlin. Наприклада один клас реалізовує певний інтерфей, інший клас може вказати, що цей інтерфейс реалізований такими то класом і використати цю реалізацію.

interface Base {
    fun print()
}

//клас, що реалізовує інтерфейс Base
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

//клас Derived делегує реалізацію інтерфейсу Base об'єкту b
class Derived(b: Base) : Base by b

fun main() {
    val base = BaseImpl(115) 
    Derived(base).print()   // 115
}

Як бачимо з прикладу клас BaseImp реалізовує наш інтерфейс. Ми передаємо класу Derived об'єктне посилання класу BaseImpl і тепер через об'єкт Derived ми можемо викликати функцію print().

Слід зазначити, що якщо ми замістимо функцію print() у класі Derived, то при виконанні буде викликана перевизначена функція print().

interface Base {
    fun print()
}

//клас, що реалізовує інтерфейс Base
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

//клас derived делегує реалізацію інтерфейсу Base об'єкту b
class Derived(b: Base) : Base by b{
    override fun print(){
        println ("New realization")
    }
}


fun main() {
    val base = BaseImpl(115)
    Derived(base).print() // New realization
}

Обережно треба із заміщенням властивостей. Якщо функція класу делегата використовує властивість, яка заміщене у похідному класі, то вона все рівно буде викликати властивість власного класу.

interface Base {
    var message:String
    fun print()
}

//клас, що реалізовує інтерфейс Base
class BaseImpl() : Base {
    override var message:String="Base"
    override fun print() { println(this.message) }
}

//клас derived делегує реалізацію інтерфейсу Base об'єкту b
class Derived(b: Base) : Base by b{
    override var message:String="Derived"
}

fun main() {
    val base = BaseImpl()
    val derived=Derived(base)
    derived.print() // Base
    println(derived.message) //Derived

}

Детальніше

[ред.]