Ответ вслух Middle Функции, расширения и scope-функции обновлено

Как работают функции расширения

Вопрос

Как устроены функции расширения, какие у них ограничения и когда их стоит использовать?

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

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

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

Коротко

Расширение позволяет добавить функцию к чужому классу без наследования. Под капотом это обычная статическая функция, у которой объект-получатель передаётся первым параметром, сам класс не меняется.

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

  • Компилируются в статическую функцию с получателем первым параметром

  • Разрешаются статически, по объявленному типу, полиморфизма нет

  • Член класса побеждает расширение

  • Нет доступа к private

  • Подходят для утилит и DSL, не для бизнес-логики, которая должна быть в классе

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

  • Можно ли объявить расширение для nullable-типа?
  • Что такое расширение с получателем в лямбде (T.() -> Unit)?
  • Как вызвать расширение из Java?

Разбор

Расширение позволяет добавить функцию к чужому классу без наследования. Под капотом это обычная статическая функция, у которой объект-получатель передаётся первым параметром, сам класс не меняется. Отсюда ограничения. Нет доступа к private-членам. Выбор расширения делается при компиляции по объявленному типу, поэтому полиморфизма нет: для переменной типа Shape вызовется расширение Shape, даже если там Circle. Если у класса есть член с той же сигнатурой, всегда побеждает член. Расширение можно объявить для nullable-типа, внутри this может быть null, так сделаны isNullOrEmpty. Я использую расширения для утилит, адаптеров и DSL, например Context.dp(...) или билдеров. Бизнес-логику, которая работает с состоянием, держу в самих классах, иначе её трудно найти и протестировать.

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

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