Jakie cechy pracy z dziedziczeniem i delegowaniem istnieją w Kotlin?
sobes.tech AI
Odpowiedź od AI
W Kotlinie domyślane dziedziczenie jest zamknięte (final), klasy i metody muszą być wyraźnie oznaczone jako open, aby umożliwić dziedziczenie i nadpisywanie. Dziedziczenie obsługiwane jest tylko z jednej klasy, ale można implementować wiele interfejsów.
Przy dziedziczeniu konstruktor klasy bazowej jest wywoływany po konstruktorze klasy pochodnej:
open class Base(val name: String) {
init { println("Inicjalizacja Base") }
open fun greeting() { println("Cześć z Base") }
}
class Derived(name: String, val age: Int) : Base(name) {
init { println("Inicjalizacja Derived") }
override fun greeting() { println("Cześć z Derived") }
}
Delegacja w Kotlinie jest realizowana na poziomie języka za pomocą słowa kluczowego by. Pozwala przekazać implementację interfejsu innemu obiektowi. To wygodna alternatywa dla dziedziczenia implementacji (które nie jest bezpośrednio obsługiwane).
interface Greeter {
fun greet(name: String)
}
class GreeterImpl : Greeter {
override fun greet(name: String) {
println("Cześć, $name!")
}
}
class DelegateGreeter(greeter: Greeter) : Greeter by greeter
Tutaj DelegateGreeter deleguje wywołanie metody greet do obiektu greeter.
Porównanie:
| Cecha | Dziedziczenie | Delegacja (by) |
|---|---|---|
| Relacja | "jest czymś" (is a) | "ma" (has a) |
| Implementacja | Bezpośrednie rozszerzenie klasy | Przekazanie implementacji do obiektu |
| Wielość | Jeden klasa bazowa | Wiele interfejsów |
| Elastyczność | Mniej elastyczne | Bardziej elastyczne, przez kompozycję |
| Widoczność | Dziedziczy protected i public | Działa przez interfejsy |
Delegacja jest często preferowana nad dziedziczeniem, aby osiągnąć elastyczność i unikać problemów "kruchych klas bazowych".