Ответ
Нет, не может. Это прямое ограничение языка Swift.
- Designated (назначенные) инициализаторы обязаны обеспечивать полную инициализацию своего класса и вызывать инициализатор суперкласса.
- Convenience (вспомогательные) инициализаторы предназначены для предоставления альтернативных точек входа для инициализации текущего класса. Они могут вызывать только другие инициализаторы того же класса (обычно designated), делегируя им основную работу.
Пример, иллюстрирующий правило:
class Vehicle {
let wheels: Int
init(wheels: Int) { self.wheels = wheels } // Designated инициализатор
}
class Car: Vehicle {
let brand: String
// Designated инициализатор подкласса
init(brand: String, wheels: Int) {
self.brand = brand
super.init(wheels: wheels) // ✅ Вызов super разрешен только здесь
}
// Convenience инициализатор
convenience init(brand: String) {
self.init(brand: brand, wheels: 4) // ✅ Вызов designated инициализатора своего класса
// super.init(wheels: 4) // ❌ Ошибка компиляции: convenience не может вызывать super
}
} Ответ 18+ 🔞
Да ты послушай, что за дичь творится в этом Swift! Ну реально, как будто нарочно придумали, чтобы мозг сломать.
Вот представь: есть у тебя класс Vehicle, там wheels. У него есть главный, designated инициализатор. Этот мужик обязан всё своё хозяйство поднять, всё проинициализировать и, если надо, суперклассу позвонить — super.init(). Он как прораб на стройке, отвечает за всё.
А теперь появляется convenience инициализатор. Это такой вспомогательный чувак, помощник. Его задача — просто дать тебе удобную точку входа. Хочешь создать Car только с brand, а wheels по умолчанию 4? Пожалуйста, вот тебе convenience init(brand: String).
И вот тут главный пиздец, блядь! Этот convenience-помощник вообще не имеет права звонить напрямую папе (super)! Ни хуя! Его единственная законная работа — позвонить другому инициализатору ВНУТРИ СВОЕГО ЖЕ КЛАССА. Обычно тому самому главному, designated.
Почему? А потому что архитектура, блядь! Чтобы цепочка делегирования была чёткой. Сначала весь твой класс должен сам себя построить (через designated), а уж потом можно звать предков. А convenience — он для мелких удобств внутри, а не для фундаментальных решений.
Смотри, как это выглядит в коде, тут всё наглядно:
class Vehicle {
let wheels: Int
init(wheels: Int) { self.wheels = wheels } // Главный (designated) инициализатор предка
}
class Car: Vehicle {
let brand: String
// Главный (designated) инициализатор наследника
init(brand: String, wheels: Int) {
self.brand = brand // 1. Сначала своё настроил
super.init(wheels: wheels) // 2. Потом позвал папу — МОЖНО!
}
// Вспомогательный (convenience) инициализатор
convenience init(brand: String) {
// А тут пытаешься super.init(wheels: 4) сделать — ХУЙ ТЕБЕ!
// Компилятор тебя нахуй пошлёт сразу.
// Единственный законный путь — позвать designated СВОЕГО класса.
self.init(brand: brand, wheels: 4) // ✅ Вот так правильно, блядь!
}
}
Вот и вся магия. Convenience — это как хитрая жопа, которая может только своё же начальство побеспокоить, но не лезть через его голову к деду. Порядок, сука, должен быть! Иначе получится пиздопроебибна в иерархии, и компилятор, который за порядком следит, просто взорвётся от возмущения.