Что делает ключевое слово `final` в Swift?

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

Ответ

final — это модификатор в Swift, который запрещает дальнейшее переопределение (override) или наследование.

Что можно пометить как final:

  1. Класс (final class): Запрещает создание подклассов от этого класса.
  2. Метод (final func): Запрещает переопределение этого метода в подклассах.
  3. Свойство (final var): Запрещает переопределение геттера/сеттера или всего свойства в подклассах.
  4. Сабскрипт (final subscript): Запрещает переопределение сабскрипта.

Примеры:

// 1. Final класс
final class Vehicle {
    // 2. Final метод
    final func startEngine() { print("Vroom!") }
    // 3. Final свойство
    final var wheelCount: Int { return 4 }
}
// Ошибка компиляции: Cannot inherit from non-open class 'Vehicle'
// class Car: Vehicle { }

class Animal {
    // Метод, который нельзя переопределить в подклассах Animal
    final func breathe() { print("Breathing...") }
}
class Dog: Animal {
    // Ошибка: Cannot override 'breathe' which has been marked as 'final'
    // override func breathe() { ... }
}

Зачем использовать final:

  1. Защита от изменений (Инкапсуляция): Гарантирует, что критическая логика класса или метода не будет случайно или ошибочно изменена в наследниках.
  2. Оптимизация производительности: Компилятор может применять агрессивные оптимизации (например, прямой вызов метода — devirtualization), зная, что реализация не может быть переопределена.
  3. Упрощение дизайна: Явно указывает, что сущность является конечной в иерархии наследования.

Важные ограничения:

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