W Kotlinie słowo kluczowe super jest używane do odwołania się do realizacji metody lub właściwości klasy nadrzędnej lub realizowanego interfejsu. W odróżnieniu od Javy, Kotlin pozwala na wyraźne wskazanie, przez który interfejs lub klasę wywołać realizację metody, co jest szczególnie ważne w przypadku "konfliktu" kilku interfejsów z takimi samymi metodami.
Cechą charakterystyczną: Jeśli klasa realizuje kilka interfejsów, w których zdefiniowana jest metoda o tej samej sygnaturze i istnieje domyślna realizacja, to należy wyraźnie wskazać, którą realizację wykorzystać.
Przykład:
interface A { fun foo() = println("A") } interface B { fun foo() = println("B") } class C : A, B { override fun foo() { super<A>.foo() // Wyraźne wywołanie A.foo super<B>.foo() // Wyraźne wywołanie B.foo } }
Nie jest to obsługiwane w Javie bezpośrednio (Java nie zezwala na posiadanie przez interfejs pola/realizacji metod do Javy 8, a nawet w Javie 8 — mechanizmy są inne).
"Czy w Kotlinie można odwołać się do realizacji metody klasy nadrzędnej przez kilka poziomów dziedziczenia?"
super<Intermediate>.foo(), ale tak nie jest — można odwołać się tylko do bezpośredniej klasy nadrzędnej lub interfejsu,
który realizuje daną metodę bezpośrednio.Przykład:
open class Base { open fun foo() = println("Base") } open class Mid : Base() { override fun foo() { println("Mid"); super.foo() } } class Child: Mid() { override fun foo() { super.foo() // wywoła Mid.foo() // super<Base>.foo() — błąd kompilacji } }
Historia
W dużym projekcie interfejsy
LoggeriAuditoroba definiowały metodęrecord(). Podczas realizacji klasy, która dziedziczyła oba interfejsy, programista nie nadpisał jawnierecord(), w efekcie pojawił się błąd kompilacji "Klasa musi nadpisać publiczną otwartą funkcję record()". Musiał zrealizować metodę ręcznie i jawnie delegować do odpowiedniego interfejsu.
Historia
Podczas próby wywołania zrealizowanej metody klasy nadrzędnej przez kilka pośrednich warstw (np.
super<Base>.foo()), wystąpił błąd kompilacji. Programista nie znał ograniczeń Kotlina i nie mógł zrozumieć, dlaczego bezpośrednie wywołanie jest niemożliwe.
Historia
Po aktualizacji API jeden z interfejsów dodał realizację funkcji domyślnej, która pokrywała się z innym interfejsem. Stary kod przestał się kompilować z powodu konfliktu realizacji — trzeba było jawnie rozwiązać konflikt, realizując metodę samodzielnie i wybierając, które realizacje superinterfejsów wywoływać wewnątrz siebie.