В чем разница между классами, объявленными как `open` и `public` (или просто `class`) в Swift?

«В чем разница между классами, объявленными как `open` и `public` (или просто `class`) в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Модификаторы доступа open и public (или его отсутствие для классов) контролируют возможность наследования и переопределения за пределами модуля, где класс объявлен.

open класс

  • Наследование: Разрешает создавать подклассы в любом модуле (как внутри, так и снаружи).
  • Переопределение: Методы, помеченные open, можно переопределять в подклассах в любом модуле.
  • Цель: Для создания публичных фреймворков, где вы ожидаете, что другие разработчики будут расширять ваш класс.

public (или неявный) класс

  • Наследование: Создание подклассов запрещено за пределами модуля, где класс объявлен.
  • Переопределение: Методы, помеченные public, нельзя переопределять за пределами модуля.
  • Цель: Для предоставления готового к использованию API, который не предназначен для наследования извне (сокрытие деталей реализации).

Пример:

// Модуль MyFramework
open class OpenVehicle {
    open func startEngine() { print("Vroom!") }
    public func honk() { print("Beep!") }
}

public class PublicCar {
    public func drive() { print("Driving") }
}

// Модуль App (импортирует MyFramework)
class MySportsCar: OpenVehicle { // OK: Наследование разрешено
    override func startEngine() { print("VROOOOM!") } // OK: Переопределение разрешено
    // override func honk() { ... } // Ошибка: метод `public`, нельзя переопределить извне
}

// class MyCustomCar: PublicCar { } // Ошибка: Наследование `public` класса извне запрещено

Итог:

  • Используйте open, если ваш класс должен быть базовым классом для других модулей.
  • Используйте public (или оставьте по умолчанию для классов внутри модуля), если вы предоставляете законченный компонент, который не должны наследовать извне (принцип «закрытости для модификации»).