Можно ли в Swift эмулировать поведение модификатора open без его использования?

Ответ

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

Основные ограничения public (альтернативы open):

  • public class — нельзя наследовать вне модуля.
  • public метод — нельзя переопределить вне модуля.

Способы эмуляции:

  1. Использование протоколов: Определите публичный протокол с требуемым интерфейсом. Внешний код может предоставить свою реализацию.
    // Внутри модуля:
    public protocol ServiceProtocol {
        func execute()
    }
    public class MyModule {
        public let service: ServiceProtocol
        public init(service: ServiceProtocol) {
            self.service = service // Внешняя реализация
        }
    }
  2. Наследование внутри модуля: Создайте публичный подкласс внутри модуля, который затем можно использовать извне.
    // Внутри модуля:
    public class Base { /* public методы */ }
    public class BaseOpen: Base { } // Публичный наследник для внешнего использования

Вывод: Полноценной семантической замены open не существует. Эти подходы лишь частично решают задачу, жертвуя прямым наследованием.

Ответ 18+ 🔞

Ну, блядь, смотри, как оно обстоит на самом деле. Ты хочешь open, а тебе дают public — и нихуя не то, да? Так вот, слушай сюда, пока я не обосрался от смеха.

В чём, сука, подвох? public — это как тёща на даче: вроде доступна, но попробуй её переделать!
public class — наследовать снаружи модуля? Не, блядь, не выйдет.
public метод — переопределить? Да хуй там плавал!
Короче, open — это «давай, еби меня в сраку, как хочешь», а public — «посмотри, но не трогай, а то в глаз получишь».

Как выкрутиться, если ты не лох?

  1. Протоколы, ёпта!
    Выносишь интерфейс в протокол, а реализацию — на откуп внешнему миру.

    // Твой модуль:
    public protocol ServiceProtocol {
       func execute()
    }
    public class MyModule {
       public let service: ServiceProtocol
       public init(service: ServiceProtocol) {
           self.service = service // Пусть сами свою хуйню подсовывают
       }
    }

    Типа: «Вот тебе правила, а как играть — твои проблемы».

  2. Наследуй внутри, блядь!
    Создаёшь публичного наследника прямо в модуле — и пусть его таскают, как хотят.

    // Опять в модуле:
    public class Base { /* public методы, но переопределять низя */ }
    public class BaseOpen: Base { } // А вот этого ублюдка — давай, насилуй!

    Это как дать ключ от гаража, но не от машины. Хуйня, но хоть что-то.

Итог, сука:
Прямой замены open — нет, блядь. Всё это костыли, которые лишь отдалённо напоминают свободу. Хочешь полный доступ — либо делай модуль открытым, либо иди нахуй с такими запросами. Вот так вот, в рот меня чих-пых!