Sobes.tech
Junior

Jak realizuje się interfejsy w Kotlinie?

sobes.tech AI

Odpowiedź od AI

Interfejsy w Kotlinie są implementowane za pomocą słowa kluczowego implements (domyślnie w Kotlinie, po prostu wskazuje się dwukropkiem) lub by do delegowania.

Główne metody implementacji:

  1. Bezpośrednia implementacja: Obiekt lub klasa bezpośrednio implementuje wszystkie członków interfejsu.
    interface MyInterface {
        fun doSomething()
        val myProperty: String
    }
    
    class MyClass : MyInterface {
        override fun doSomething() {
            println("Robię coś w MyClass")
        }
    
        override val myProperty: String = "Cześć"
    }
    
    Przy dziedziczeniu po klasie i implementacji interfejsów jednocześnie, klasa jest wskazywana jako pierwsza.
    open class BaseClass
    
    class AnotherClass : BaseClass(), MyInterface {
        override fun doSomething() {
            println("Robię coś w AnotherClass")
        }
    
        override val myProperty: String = "Świat"
    }
    
  2. Delegacja implementacji: Implementacja interfejsu jest delegowana do innego obiektu. Używa się słowa kluczowego by. Jest to przydatne do kompozycji i unikania problemów z wielokrotnym dziedziczeniem implementacji.
    interface DelegatedInterface {
        fun performAction()
    }
    
    class DelegatedObject : DelegatedInterface {
        override fun performAction() {
            println("Akcja wykonana przez DelegatedObject")
        }
    }
    
    class ImplementingClass(di: DelegatedInterface) : DelegatedInterface by di {
        // ImplementingClass deleguje implementację metody performAction() do obiektu di
    }
    
    W tym przypadku, ImplementingClass nie implementuje performAction samodzielnie, zamiast tego wywołanie performingClass.performAction() jest przekierowywane na di.performAction().

Przy implementacji wielu interfejsów z członkami o tej samej nazwie, konieczne jest rozwiązywanie konfliktów, jawnie nadpisując członka i wskazując, z którego interfejsu pochodzi implementacja, używając składni <Interfejs>.<członek>.

interface InterfaceA {
    fun foo() { println("InterfaceA") }
    fun bar()
}

interface InterfaceB {
    fun foo() { println("InterfaceB") }
    fun bar() { println("InterfaceB bar") }
}

class ResolvingConflict : InterfaceA, InterfaceB {
    override fun foo() {
        super<InterfaceA>.foo() // Wywołujemy implementację foo z InterfaceA
        super<InterfaceB>.foo() // Wywołujemy implementację foo z InterfaceB
    }

    override fun bar() {
        super<InterfaceB>.bar() // Używamy implementacji bar z InterfaceB
    }
}