Ответ вслух Senior Делегаты обновлено

Делегирование вместо наследования

Вопрос

Как в Kotlin работает делегирование реализации интерфейса через by и когда ты его используешь?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Запись class Cached(inner: Repo) : Repo by inner говорит компилятору сгенерировать все методы интерфейса Repo, которые просто вызывают inner, а я переопределяю только те, что нужно изменить, например добавляю кеш в load.

Что должно прозвучать в ответе

  • Компилятор генерирует методы интерфейса, переадресующие делегату

  • Переопределяются только нужные методы

  • Композиция вместо наследования, работает с final-классами

  • Делегат фиксируется при создании

  • Делегат не видит переопределений обёртки: нет полиморфизма через this

Что могут спросить следом

  • Чем это отличается от наследования от open-класса?
  • Где в Android это полезно?

Разбор

Запись class Cached(inner: Repo) : Repo by inner говорит компилятору сгенерировать все методы интерфейса Repo, которые просто вызывают inner, а я переопределяю только те, что нужно изменить, например добавляю кеш в load. Так реализуется декоратор без десятков методов-прокладок, и это работает даже когда реализация final, что в Kotlin бывает по умолчанию. Важно понимать отличие от наследования: делегат фиксируется в момент создания объекта, и если внутри делегата метод вызывает другой свой метод, он вызывает свою версию, а не переопределённую в обёртке. То есть полиморфизма через this нет. Использую это для логирования, кеширования, метрик вокруг репозиториев и для комбинирования поведения из нескольких интерфейсов.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.