Ключевое слово 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 — локальная установка не требуется.
Все уроки этого курса
- Ключевое слово by
- Делегирование членам
- Делегирование и наследование
- Практические шаблоны