Delegowanie a dziedziczenie
Wybieraj kompozycję
Delegowanie a dziedziczenie to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Dwa sposoby ponownego wykorzystania
Dziedziczenie i delegowanie pozwalają ponownie wykorzystywać zachowanie. Dziedziczenie oznacza, że klasa jest rodzajem innej klasy. Delegowanie oznacza, że klasa ma współpracownika, do którego przekazuje wywołania.
Klasyczna zasada mówi: należy preferować kompozycję zamiast dziedziczenia.
Przykład dziedziczenia
W przypadku dziedziczenia podklasa rozszerza klasę bazową i przesłania jej elementy. W Kotlinie klasa bazowa musi być oznaczona jako open.
open class Animal {
open fun sound() = "..."
}
class Dog : Animal() {
override fun sound() = "woof"
}
fun main() {
println(Dog().sound())
}Przykład delegowania
Takie samo ponowne wykorzystanie z użyciem delegowania: zachowanie znajduje się w składowej, do której klasa przekazuje wywołania.
interface Sound { fun sound(): String }
class Bark : Sound { override fun sound() = "woof" }
class Dog(s: Sound) : Sound by s
fun main() {
println(Dog(Bark()).sound())
}Krucha klasa bazowa
Dziedziczenie silnie wiąże klasę potomną z wewnętrznym działaniem klasy nadrzędnej. Zmiana w klasie bazowej może po cichu zepsuć klasy potomne — to problem kruchej klasy bazowej. Delegowanie zależy tylko od interfejsu.
Hermetyzacja
Klasa potomna może uzyskiwać dostęp do składowych chronionych i zastępować punkty rozszerzeń, zaglądając do wnętrza klasy nadrzędnej. Klasa delegująca widzi tylko publiczny interfejs, zachowując hermetyzację.
interface Counter { fun increment(): Int }
class SimpleCounter : Counter {
private var n = 0
override fun increment(): Int { n++; return n }
}
class GuardedCounter(private val c: Counter) : Counter by c {
override fun increment(): Int {
println("incrementing")
return c.increment()
}
}
fun main() {
val g = GuardedCounter(SimpleCounter())
println(g.increment())
println(g.increment())
}Elastyczność w czasie wykonywania
Dziedziczenie ustala klasę nadrzędną w czasie kompilacji. Delegowanie pozwala wstrzykiwać różne implementacje w czasie wykonywania, co ułatwia testowanie za pomocą atrap.
interface Clock { fun now(): Int }
class RealClock : Clock { override fun now() = 100 }
class FakeClock : Clock { override fun now() = 0 }
class Timer(c: Clock) : Clock by c
fun main() {
println(Timer(RealClock()).now())
println(Timer(FakeClock()).now()) // easy to test
}Wiele zachowań
Klasa może rozszerzać tylko jedną klasę nadrzędną, ale może delegować do wielu interfejsów. Delegowanie dobrze skaluje się przy łączeniu wielu możliwości.
interface Walk { fun walk() = "walking" }
interface Swim { fun swim() = "swimming" }
class Walker : Walk
class Swimmer : Swim
class Amphibian : Walk by Walker(), Swim by Swimmer()
fun main() {
val a = Amphibian()
println(a.walk() + ", " + a.swim())
}Kiedy sprawdza się dziedziczenie
Dziedziczenie nadal jest właściwe dla prawdziwej relacji is-a oraz stabilnej hierarchii zaprojektowanej z myślą o rozszerzaniu: zapieczętowanych rodzin typów, bazowych klas frameworków i polimorfizmu opartego na wspólnym typie abstrakcyjnym.
sealed class Shape
class Circle(val r: Double) : Shape()
class Square(val s: Double) : Shape()
fun area(shape: Shape) = when (shape) {
is Circle -> 3.14 * shape.r * shape.r
is Square -> shape.s * shape.s
}
fun main() {
println(area(Circle(2.0)))
}Kiedy sprawdza się delegowanie
Wybierz delegowanie, gdy chcesz:
- Ponownie wykorzystywać zachowanie w niezwiązanych ze sobą typach
- Łączyć wiele możliwości
- Utrzymywać luźne powiązania i ułatwiać testowanie
- Opakowywać i dekorować istniejące implementacje
Porównanie
Dziedziczenie: jedna klasa nadrzędna, silne powiązanie, ustalone w czasie kompilacji, is-a. Delegowanie: wielu współpracowników, luźne powiązanie, możliwość wymiany w czasie wykonywania, has-a. Kotlin upraszcza delegowanie za pomocą by, przechylając szalę na korzyść kompozycji.
Praktyczny wybór domyślny
Dobra zasada: należy zaczynać od delegowania. Do dziedziczenia warto przechodzić dopiero wtedy, gdy wyłoni się rzeczywista, stabilna hierarchia is-a. Dzięki temu projekty pozostają elastyczne i odporne na zmiany.
Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat delegowania i dziedziczenia.
Podsumowanie
Porównano dwa podejścia:
- Dziedziczenie: is-a, jedna klasa nadrzędna, silne powiązanie
- Delegowanie: has-a, wielu współpracowników, luźne powiązanie
- Preferuj kompozycję; używaj dziedziczenia w stabilnych hierarchiach is-a
Następnie: praktyczne wzorce dekoratora z użyciem delegowania.
Często zadawane pytania
Czy lekcja „Delegowanie a dziedziczenie” jest bezpłatna?
Tak — pełny tekst „Delegowanie a dziedziczenie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Delegowanie a dziedziczenie”?
Wybieraj kompozycję Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?
Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Delegowanie a dziedziczenie”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?
Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Słowo kluczowe by
- Delegowanie do składowych
- Delegowanie a dziedziczenie
- Praktyczne wzorce