0Pricing
Kotlin Academy · Lekcja

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

  1. Słowo kluczowe by
  2. Delegowanie do składowych
  3. Delegowanie a dziedziczenie
  4. Praktyczne wzorce
← Powrót do Kotlin Academy