Делегирование вместо наследования
Вопрос
Как в Kotlin работает делегирование реализации интерфейса через by и когда ты его используешь?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Компилятор генерирует методы интерфейса, переадресующие делегату
Переопределяются только нужные методы
Композиция вместо наследования, работает с final-классами
Делегат фиксируется при создании
Делегат не видит переопределений обёртки: нет полиморфизма через this
Что могут спросить следом
- Чем это отличается от наследования от open-класса?
- Где в Android это полезно?
Разбор
Запись class Cached(inner: Repo) : Repo by inner говорит компилятору сгенерировать все методы интерфейса Repo, которые просто вызывают inner, а я переопределяю только те, что нужно изменить, например добавляю кеш в load. Так реализуется декоратор без десятков методов-прокладок, и это работает даже когда реализация final, что в Kotlin бывает по умолчанию. Важно понимать отличие от наследования: делегат фиксируется в момент создания объекта, и если внутри делегата метод вызывает другой свой метод, он вызывает свою версию, а не переопределённую в обёртке. То есть полиморфизма через this нет. Использую это для логирования, кеширования, метрик вокруг репозиториев и для комбинирования поведения из нескольких интерфейсов.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.