Swift: Access Control (контроль доступа)

Мы будем называть все к чему можно применить контроль доступа — записи (entries)
Контроль доступа ограничивает доступ к указанным записям в других исходных файлах и модулях. Уровень доступа можно назначить как типам, так и их членам. Существует так же права доступа по умолчанию, чтобы не приходилось их выставлять для всех членов. Уровень по умолчанию — internal

Модуль — отдельная единица кода — фреймворк или приложение, которое скомпилировано и поставляется как единая единица и может быть включена в код с помощью ключевого слова import.

Исходный файл — отдельный файл с исходным кодом внутри модуля.

Уровни доступа:
public (публичный, самый высокий) — позволяет записям использоваться везде, как внутри этого модуля так и других
internal (внутренний) — позволяет записям использоваться везде внутри этого модуля
private (приватный, самый низкий) — записи можно использовать только внутри этого исходного файла

Основное правило уровня доступа — ни одна запись не может быть определена внутри другой записи, которая имеет уровень доступа ниже.
Т.е. такая запись неверная, т.к. родительский тип имеет уровень доступа private, а его внутренняя запись public

То же касается и функции: функция не может иметь более высокий уровень доступа чем ее параметры или возвращаемое значение

Когда пишешь обычное приложение — internal уровень доступа вполне подходит за редким исключением.
А вот при написании фреймворка — те методы и типы, которые образуют API — нужно делать public

Если присваиваешь уровень доступа типу — все его члены автоматически изменяют свой уровень доступа на такой же (но члены public типа по умолчанию все равно остаются internal). Т.е. если рассмотреть схему родитель — его члены, то она будет такой

public — internal
internal — internal
private — private

Для кортежа и функции — уровень доступа равный наименьшему уровню среди всех входящих в него типов (для функции учитывается и возвращаемое значение). Но если для кортежа уровень доступа вычисляется автоматически — для функции в случае не совпадении вычисленного уровня с уровнем доступа по умолчанию для содержащего ее типа — необходимо указывать уровень доступа явно.

В перечислениях индивидуальные case получают тот же доступ что и сам enum
Если используются RawValue — их тип должен иметь уровень доступа >= чем уровень доступа enum

При наследовании типа уровень доступа ребенка должен быть <= уровня доступа родителя. Но члены этого типа при переопределении может получить любой уровень доступа, при этом можно из переопределенного метода вызывать родительский даже если родительский имеет меньший уровень доступа.

Константа, переменная и свойство должны иметь уровень доступа <= чем их тип

нельзя переменную сделать public, т.к. тип SomePrivateClassprivate

Getters и Setters — автоматически получают уровень доступа константы/переменной/свойства/индекса к которым они принадлежат
Можно понизить, нельзя повысить. Понижение полезно, если переменная должна быть доступна на получение везде, а на установку только внутри исходного файла к примеру

В этом случае get получит уровень по умолчанию. Если нужно указать явно то делаем так

У инициализаторов уровень должен быть <= уровня типа к которому они принадлежат. Но уровень required init == уровню типа.
Уровень параметров инициализатора >= уровня инициализатора

Уровень инициализатора по умолчанию == уровню типа, но если уровень типа == public, то уровень инициализатора по умолчанию = internal

Уровень доступа почленного инициализатора для типа структуры = private, если хоть один член хранимого свойства имеет private уровень, иначе = internal

Уровень доступа членов протокола — уровню доступа самого протокола
Уровень доступа наследника протокола <= уровню доступа родительского протокола Тип может реализовать протокол имеющим уровень доступа меньше чем у самого типа. Члены внутри расширения наследуют права по стандартным правилам. Если родительский уровень == public/internal — то члены = internal, а если private, то private
Можно явно указывать уровень доступа (private extension к примеру)
Но это нельзя применять если, расширение используется для добавления соответствию протоколу

т.е. так нельзя, private нужно убрать

Уровень доступа типа или функции дженерика = минимальному уровню всех членов
Уровень доступа связанных типов <= уровню доступа типа для которого они являются псевдонимом

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *