Какие уровни контроля доступа существуют в Swift и для чего они нужны?

«Какие уровни контроля доступа существуют в Swift и для чего они нужны?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Контроль доступа (Access Control) в Swift определяет видимость и возможность использования сущностей (классов, свойств, методов) из других файлов или модулей. Это основа инкапсуляции и проектирования API.

Уровни доступа (от самого открытого к самому строгому):

Уровень Видимость Основное назначение
open Любой модуль. Наследование и переопределение из любого модуля. Для публичного фреймворка, когда вы хотите позволить другим разрабатывать на его основе. Только для классов.
public Любой модуль. Наследование/переопределение только внутри модуля, где объявлен класс. Для публичного API фреймворка или библиотеки.
internal (по умолчанию) Только внутри модуля (target). Для внутренней логики приложения или модуля. Скрывает детали реализации.
fileprivate Только внутри исходного файла. Чтобы использовать сущность в нескольких типах внутри одного файла, скрыв её от остальной части модуля.
private Наиболее ограниченный. Только внутри объявляющей области (типа или расширения). Для сокрытия деталей реализации конкретного типа.

Практические примеры:

// Фреймворк 'NetworkKit'
public class APIClient { // Публичный API
    internal var session: URLSession // Внутренняя деталь реализации
    private var authToken: String? // Секрет, недоступный даже внутри модуля

    fileprivate func log(_ message: String) { // Для использования в расширениях в этом файле
        print("[APIClient]", message)
    }
}

open class CustomViewController: UIViewController { // Можно наследовать в другом модуле
    open func customizableMethod() { }
    public func publicMethod() { } // Можно использовать, но не переопределять вне модуля
}

// В том же файле, что и APIClient
extension APIClient {
    func debugInfo() {
        log("Debug") // Доступно, так как расширение в том же файле
        // print(authToken) // Ошибка: 'authToken' is private
    }
}

Ключевое правило:

Уровень доступа сущности не может быть ниже, чем уровень доступа её типов. Например, нельзя объявить public-метод, который возвращает private-тип.