W tym artykule dowiesz się o interfejsach i jak je wdrożyć w Kotlinie na przykładach.
Interfejsy Kotlin są podobne do interfejsów w Javie 8. Mogą zawierać definicje metod abstrakcyjnych, a także implementacje metod nieabstrakcyjnych. Nie mogą jednak zawierać żadnego stanu.
Oznacza to, że interfejs może mieć właściwość, ale musi być abstrakcyjny lub musi zapewniać implementacje akcesorów.
Zalecana literatura: Klasa abstrakcyjna Kotlina
Klasy abstrakcyjne w Kotlinie są podobne do interfejsu z jedną istotną różnicą. Nie jest obowiązkowe, aby właściwości klasy abstrakcyjnej były abstrakcyjne lub zapewniały implementacje akcesorów.
Jak zdefiniować interfejs?
Słowo kluczowe interface
służy do definiowania interfejsów w Kotlin. Na przykład,
interfejs MyInterface (var test: String // abstract property fun foo () // abstract method fun hello () = "Hello there" // metoda z domyślną implementacją)
Tutaj,
- tworzony jest interfejs MyInterface.
- interfejs zawiera abstrakcyjny test właściwości i abstrakcyjną metodę
foo()
. - interfejs ma również metodę nieabstrakcyjną
hello()
.
Jak zaimplementować interfejs?
Oto jak klasa lub obiekt może implementować interfejs:
interfejs MyInterface (val test: Int // abstract property fun foo (): String // abstract method (return String) fun hello () (// metoda z domyślną implementacją // body (opcjonalne))) class InterfaceImp: MyInterface (override val test: Int = 25 override fun foo () = "Lol" // inny kod)
Tutaj klasa InterfaceImp implementuje interfejs MyInterface.
Klasa przesłania abstrakcyjne elementy członkowskie (właściwość i foo()
metodę testową ) interfejsu.
Przykład: Jak działa interfejs?
interface MyInterface ( val test: Int fun foo() : String fun hello() ( println("Hello there, pal!") ) ) class InterfaceImp : MyInterface ( override val test: Int = 25 override fun foo() = "Lol" ) fun main(args: Array) ( val obj = InterfaceImp() println("test = $(obj.test)") print("Calling hello(): ") obj.hello() print("Calling and printing foo(): ") println(obj.foo()) )
Po uruchomieniu programu wynik będzie następujący:
test = 25 Wołanie hello (): Witaj, stary! Wywołanie i drukowanie foo (): Lol
Jak wspomniano powyżej, interfejs może również mieć właściwość zapewniającą implementację metody dostępu. Na przykład,
interface MyInterface ( // property with implementation val prop: Int get() = 23 ) class InterfaceImp : MyInterface ( // class body ) fun main(args: Array) ( val obj = InterfaceImp() println(obj.prop) )
Po uruchomieniu programu wynik będzie następujący:
23
Tutaj rekwizyt nie jest abstrakcyjny. Jednak jest ważna w interfejsie, ponieważ zapewnia implementację dla akcesora.
Nie możesz jednak zrobić czegoś takiego val prop: Int = 23
w interfejsie.
Implementowanie dwóch lub więcej interfejsów w klasie
Kotlin nie zezwala na prawdziwe wielokrotne dziedziczenie. Istnieje jednak możliwość zaimplementowania dwóch lub więcej interfejsów w jednej klasie. Na przykład,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMeToo() ( println("From interface B") ) ) // implements two interfaces A and B class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() obj.callMeToo() )
Po uruchomieniu programu wynik będzie następujący:
Z interfejsu A Z interfejsu B
Rozwiązywanie konfliktów zastępujących (wiele interfejsów)
Załóżmy, że dwa interfejsy (A i B) mają metodę nieabstrakcyjną o tej samej nazwie (powiedzmy callMe()
metoda). Zaimplementowałeś te dwa interfejsy w klasie (powiedzmy C). Teraz, jeśli wywołasz callMe()
metodę przy użyciu obiektu klasy C, kompilator zgłosi błąd. Na przykład,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() )
Oto błąd:
Błąd: (14, 1) Kotlin: Klasa 'C' musi nadpisać publiczną otwartą zabawę callMe (): Jednostka zdefiniowana w A, ponieważ dziedziczy wiele metod jej interfejsu
Aby rozwiązać ten problem, musisz dostarczyć własną implementację. Oto jak:
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class C: A, B ( override fun callMe() ( super.callMe() super.callMe() ) ) fun main(args: Array) ( val obj = C() obj.callMe() )
Teraz po uruchomieniu programu wynik będzie następujący:
Z interfejsu A Z interfejsu B
Tutaj jawna implementacja callMe()
metody jest dostarczona w klasie C.
klasa C: A, B (nadpisanie zabawy callMe () (super.callMe () super .callMe ()))
Instrukcja super.callMe()
wywołuje callMe()
metodę klasy A. Podobnie wywołuje metodę klasy .super.callMe()
callMe()
B