0Pricing
Kotlin Academy · Lekcja

Delegowanie do składowych

Komponuj zachowanie

Delegowanie do składowych to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 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.

Komponowanie zachowania

Rzeczywiste obiekty często muszą łączyć kilka możliwości. Zamiast dziedziczyć z wielu źródeł, można delegować każdą możliwość do osobnego obiektu składowego.

Dwie role, jedna klasa

Załóżmy, że klasa powinna zarówno odczytywać, jak i zapisywać dane. Należy zdefiniować dwa interfejsy i delegować każdy z nich do własnej implementacji.

interface Reader { fun read(): String }
interface Writer { fun write(s: String): String }

class FileReader : Reader { override fun read() = "contents" }
class FileWriter : Writer { override fun write(s: String) = "wrote " + s }

class FileIO(r: Reader, w: Writer) : Reader by r, Writer by w

fun main() {
    val io = FileIO(FileReader(), FileWriter())
    println(io.read())
    println(io.write("data"))
}

Wielu delegatów

Klasa może jednocześnie delegować kilka interfejsów, każdy do innego elementu składowego. Klasa komponuje ich zachowania bez dziedziczenia.

interface Logger { fun log(m: String): String }
interface Validator { fun valid(m: String): Boolean }

class ConsoleLogger : Logger { override fun log(m: String) = "LOG: " + m }
class LengthValidator : Validator { override fun valid(m: String) = m.isNotEmpty() }

class Service(l: Logger, v: Validator) : Logger by l, Validator by v

fun main() {
    val s = Service(ConsoleLogger(), LengthValidator())
    println(s.valid("hi"))
    println(s.log("started"))
}

Delegat przechowywany jako element składowy

Gdy potrzebna jest referencja do delegata wewnątrz przesłoniętych elementów, należy przechowywać go jako właściwość konstruktora. Ta sama instancja obsługuje zarówno przekazywanie wywołań, jak i własny kod.

interface Cache { fun get(k: String): String }

class MapCache : Cache {
    override fun get(k: String) = "value-of-" + k
}

class TracingCache(private val inner: Cache) : Cache by inner {
    override fun get(k: String): String {
        println("lookup " + k)
        return inner.get(k)
    }
}

fun main() {
    println(TracingCache(MapCache()).get("id"))
}

Łączenie delegowania z własnym stanem

Klasa delegująca może dodawać własne właściwości i metody obok elementów, do których przekazywane są wywołania, wzbogacając skomponowany obiekt.

interface Engine { fun start(): String }
class V8 : Engine { override fun start() = "vroom" }

class Car(e: Engine) : Engine by e {
    var doors = 4
    fun honk() = "beep"
}

fun main() {
    val c = Car(V8())
    println(c.start())
    println(c.honk())
    println(c.doors)
}

Zamiana implementacji

Ponieważ delegat jest zwykłym elementem składowym, ten sam typ opakowania można tworzyć z różnymi implementacjami bazowymi, wybierając zachowanie w czasie wykonywania.

interface Notifier { fun send(msg: String): String }
class EmailNotifier : Notifier { override fun send(msg: String) = "email: " + msg }
class SmsNotifier : Notifier { override fun send(msg: String) = "sms: " + msg }

class Alerts(n: Notifier) : Notifier by n

fun main() {
    println(Alerts(EmailNotifier()).send("hi"))
    println(Alerts(SmsNotifier()).send("hi"))
}

Delegowanie do właściwości

Wyrażenie po by może być dowolnym wyrażeniem obliczanym jednokrotnie, w tym wywołaniem konstruktora. Nie musi być parametrem.

interface Greeter { fun greet() = "hi" }
class DefaultGreeter : Greeter

class Page : Greeter by DefaultGreeter()

fun main() {
    println(Page().greet())
}

Unikanie problemu diamentu

Wielokrotne dziedziczenie zachowania jest niemożliwe w przypadku klas, ale delegowanie kilku interfejsów do osobnych elementów składowych pozwala w elegancki sposób ominąć klasyczny problem diamentu.

interface A { fun a() = "A" }
interface B { fun b() = "B" }
class AImpl : A
class BImpl : B

class Combined : A by AImpl(), B by BImpl()

fun main() {
    val c = Combined()
    println(c.a() + c.b())
}

Projektowanie z myślą o kompozycji

Aby dobrze komponować zachowanie:

  • Należy definiować małe, wyspecjalizowane interfejsy
  • Należy udostępniać wielokrotnego użytku implementacje
  • Należy delegować każdą rolę w komponującej klasie

Dzięki temu klasy pozostają elastyczne i łatwe do testowania.

Podsumowanie delegowania do elementów składowych

Delegowanie do obiektów składowych pozwala klasie składać zachowanie z części. Można łączyć wiele interfejsów, przesłaniać je wybiórczo, zamieniać implementacje i dodawać własny stan — wszystko bez dziedziczenia.

Następnie: bezpośrednie porównanie

Przedstawiono elastyczność delegowania. Następna lekcja bezpośrednio porównuje delegowanie z dziedziczeniem, aby ułatwić wybór właściwego rozwiązania.

Szybkie sprawdzenie

Warto sprawdzić zrozumienie delegowania do elementów składowych.

Podsumowanie

Omówiono delegowanie do elementów składowych:

  • Delegowanie kilku interfejsów do osobnych obiektów
  • Wybiórcze przesłanianie i dodawanie własnego stanu
  • Zamiana implementacji podczas tworzenia obiektu
  • Unikanie problemów związanych z wielokrotnym dziedziczeniem

Następnie: delegowanie a dziedziczenie.

Często zadawane pytania

Czy lekcja „Delegowanie do składowych” jest bezpłatna?

Tak — pełny tekst „Delegowanie do składowych” 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 do składowych”?

Komponuj zachowanie Ć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 2 z 4.

Ile czasu zajmuje lekcja „Delegowanie do składowych”?

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