0Pricing
Kotlin Academy · Урок

Ключевое слово by

Делегируйте реализацию интерфейса

«Ключевое слово by» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Что такое делегирование

Делегирование классов позволяет одному объекту передать реализацию интерфейса другому объекту. В Kotlin это встроено в язык с помощью ключевого слова by.

Это композиция без лишних усилий.

Интерфейс для делегирования

Начните с интерфейса и конкретной реализации. Позже мы передадим этой реализации делегирование.

interface Speaker {
    fun speak(): String
}

class LoudSpeaker : Speaker {
    override fun speak() = "HELLO!"
}

fun main() {
    println(LoudSpeaker().speak())
}

Ключевое слово делегирования

Напишите class X(d: Iface) : Iface by d. Компилятор создаёт методы перенаправления, которые вызывают d для каждого члена интерфейса.

interface Speaker {
    fun speak(): String
}

class LoudSpeaker : Speaker {
    override fun speak() = "HELLO!"
}

class Announcer(s: Speaker) : Speaker by s

fun main() {
    val a = Announcer(LoudSpeaker())
    println(a.speak())
}

Без шаблонного кода

Без by пришлось бы вручную писать метод перенаправления для каждой функции интерфейса. Делегирование автоматически создаёт их все.

interface Repository {
    fun save(item: String): String
    fun count(): Int
}

class MemoryRepo : Repository {
    private val items = mutableListOf<String>()
    override fun save(item: String): String { items.add(item); return item }
    override fun count() = items.size
}

class LoggingRepo(r: Repository) : Repository by r

fun main() {
    val repo = LoggingRepo(MemoryRepo())
    repo.save("a")
    println(repo.count())
}

Переопределение отдельных членов

Можно переопределить только те члены, которые Вы хотите настроить; остальные по-прежнему будут перенаправляться делегату.

interface Repository {
    fun save(item: String): String
    fun count(): Int
}

class MemoryRepo : Repository {
    private val items = mutableListOf<String>()
    override fun save(item: String): String { items.add(item); return item }
    override fun count() = items.size
}

class LoggingRepo(private val r: Repository) : Repository by r {
    override fun save(item: String): String {
        println("saving " + item)
        return r.save(item)
    }
}

fun main() {
    val repo = LoggingRepo(MemoryRepo())
    repo.save("book")
    println(repo.count())
}

Делегат как параметр

Обычно делегат передаётся через основной конструктор. Если Вы также переопределяете некоторые члены, ссылку на него можно сохранить с помощью private val.

interface Clock { fun now(): Int }

class FixedClock : Clock { override fun now() = 12 }

class App(private val clock: Clock) : Clock by clock

fun main() {
    println(App(FixedClock()).now())
}

Делегирование стандартных интерфейсов

Можно делегировать встроенным интерфейсам коллекций и сразу получить обёртку, которая ведёт себя как базовая коллекция.

class TaggedList(private val inner: List<String>) : List<String> by inner {
    val tag = "v1"
}

fun main() {
    val tl = TaggedList(listOf("x", "y"))
    println(tl.size)
    println(tl[0])
    println(tl.tag)
}

Как это компилируется

Внутри компилятор сохраняет делегат и создаёт реализации перенаправления. Сгенерированные методы просто вызывают соответствующий метод делегата. Это то же самое, что написанное вручную перенаправление, только без ручного набора кода.

Захваченный снимок

Важная тонкость: ссылка на делегат сохраняется при создании объекта. Переопределённые члены явно вызывают делегат, а сгенерированные методы перенаправления используют исходный переданный экземпляр.

interface Source { fun value(): Int }

class Const(val n: Int) : Source { override fun value() = n }

class Wrapper(s: Source) : Source by s

fun main() {
    val w = Wrapper(Const(42))
    println(w.value())
}

Зачем использовать делегирование

Ключевое слово by позволяет:

  • Повторно использовать существующие реализации
  • Добавлять поведение без наследования
  • Избегать хрупких иерархий наследования

Это полноценная встроенная поддержка Kotlin принципа композиции вместо наследования.

Основа

Ключевое слово by — основа всего этого курса. Далее мы подробнее рассмотрим делегирование объектам-членам для объединения поведения.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете ключевое слово делегирования.

Итоги

Вы изучили делегирование классов с помощью by:

  • Передачу интерфейса другому объекту
  • Автоматически созданные методы перенаправления
  • Переопределение отдельных членов при перенаправлении остальных
  • Работу со встроенными интерфейсами

Далее: делегирование членам для объединения поведения.

Часто задаваемые вопросы

Урок «Ключевое слово by» бесплатный?

Да — полный текст урока «Ключевое слово by» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Ключевое слово by»?

Делегируйте реализацию интерфейса Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Ключевое слово by»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Ключевое слово by
  2. Делегирование членам
  3. Делегирование и наследование
  4. Практические шаблоны
← Назад к Kotlin Academy