Какие отличия и последствия имеет непомеченный как `final` дочерний класс в Swift?

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

Ответ

Класс, не помеченный ключевым словом final, может быть унаследован далее. Это влечет за собой последствия для дизайна, безопасности и производительности.

Отличия и последствия:

Аспект Не-final класс final класс
Наследование Можно создать подкласс. Наследование запрещено компилятором.
Полиморфизм Методы могут быть переопределены в подклассах. Переопределение методов невозможно.
Инкапсуляция Риск нарушения, если базовый класс не проектировался для наследования. Полная инкапсуляция реализации.
Оптимизация Динамическая диспетчеризация (виртуальная таблица). Статическая диспетчеризация, возможна инлайнизация.
Безопасность Контракт класса может быть нарушен подклассом. Контракт гарантирован.

Пример цепочки наследования:

class Vehicle { // Не final
    func startEngine() { print("Engine started") }
}

class Car: Vehicle {
    override func startEngine() {
        super.startEngine()
        print("Car systems check OK")
    }
}
// Теперь от Car тоже можно наследоваться
class SportsCar: Car { // Это возможно
    override func startEngine() {
        print("Boost engaged")
        super.startEngine()
    }
}

Рекомендация (Swift Best Practice): Помечайте класс как final по умолчанию. Снимайте модификатор final только тогда, когда вы намеренно проектируете класс для наследования и документируете, как его безопасно переопределять.