Какой порядок вызова инициализаторов при наследовании классов в Swift?

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

Ответ

Порядок вызова инициализаторов в Swift строго регламентирован для обеспечения полной инициализации всех свойств.

Основное правило:

  1. Инициализация свойств текущего класса (назначение значений всем stored-свойствам, объявленным в этом классе).
  2. Вызов designated-инициализатора родительского класса (super.init(...)).
  3. Дополнительная настройка (можно изменять унаследованные свойства, вызывать методы).

Пример:

class Vehicle {
    var wheels: Int
    init(wheels: Int) {
        self.wheels = wheels // 1. Инициализация свойств Vehicle
        print("Vehicle init")
    }
}

class Car: Vehicle {
    var brand: String

    init(brand: String, wheels: Int) {
        // ФАЗА 1: Инициализация свойств Car
        self.brand = brand
        // ФАЗА 2: Вызов инициализатора родителя
        super.init(wheels: wheels)
        // ФАЗА 3: Дополнительная настройка
        self.wheels = 4 // Можно изменить унаследованное свойство
        print("Car init")
    }
}

let myCar = Car(brand: "Toyota", wheels: 0)
// Вывод:
// Vehicle init
// Car init

Ключевые ограничения:

  • Нельзя обращаться к self (включая вызов методов) до завершения Фазы 1.
  • Нельзя изменять унаследованные свойства до вызова super.init().
  • Convenience-инициализаторы должны в конечном счёте вызвать designated-инициализатор своего же класса.