Какие модификаторы доступа существуют в Kotlin и каковы их области видимости
Что проверяют
Знаете ли вы четыре модификатора и понимаете ли, чем protected и internal отличаются от Java.
Как отвечать
Модификаторов четыре: public, private, protected, internal. По умолчанию public, и это первое отличие от Java, где по умолчанию видимость на уровне пакета.
Для членов класса:
private: только внутри этого класса;protected: этот класс и наследники. Пакет сюда не входит, в отличие от Java, гдеprotectedдаёт ещё и доступ из своего пакета;internal: везде внутри модуля;public: везде.
Для объявлений верхнего уровня (функция, класс, свойство прямо в файле):
private: только внутри этого файла;internal: внутри модуля;public: везде;protectedнедоступен вовсе, наследовать тут нечего.
Ключевое понятие это модуль: набор файлов, компилируемых вместе. Практически это модуль Gradle или Maven, отдельный модуль IntelliJ, набор файлов одной задачи компиляции. internal заменяет отсутствующую видимость на уровне пакета и работает лучше неё: пакет чужой код может подделать, объявив у себя тот же пакет, а модуль нет.
Важная деталь про совместимость: internal в байт-коде становится public с искажённым именем. Значит из Java-кода такой член виден, просто обращаться к нему неудобно. Полагаться на internal как на защиту от Java в смешанном проекте нельзя.
Ещё стоит знать, что видимость конструктора задаётся отдельно (class Foo private constructor(...)), а у сеттера свойства она может быть уже, чем у геттера: var state: Int = 0; private set.
Где спотыкаются
Считают, что protected в Kotlin работает как в Java и открывает доступ пакету.
Ищут аналог видимости на уровне пакета и не знают про internal.
Думают, что internal недоступен из Java.
Не знают, что у сеттера можно сузить видимость отдельно.