Ответ
Нет, нельзя. Расширения (extension) в Swift предназначены для добавления новой функциональности к существующему типу, но не для переопределения существующих методов, свойств или инициализаторов.
Почему это запрещено:
- Безопасность и предсказуемость: Если бы переопределение в расширениях было разрешено, поведение программы могло бы непредсказуемо меняться в зависимости от того, какое расширение было скомпилировано и подключено позднее.
- Динамическая диспетчеризация: Переопределение требует динамической диспетчеризации (для классов), которая работает только для членов, объявленных в основном теле класса или его иерархии.
Правильный способ переопределения:
class Vehicle {
func description() -> String {
return "Транспортное средство"
}
}
class Car: Vehicle {
// Переопределение должно быть в основном объявлении класса
override func description() -> String {
return "Автомобиль"
}
}
// НЕВЕРНО: Это вызовет ошибку компиляции.
// extension Vehicle {
// override func description() -> String { return "Что-то" }
// }
Что можно делать в extension:
- Добавлять новые методы и вычисляемые свойства.
- Реализовывать протоколы.
- Добавлять удобные инициализаторы (
convenience init). - Добавлять сабскрипты.
Обходной путь (осторожно!): Можно добавить в extension новый метод с другим именем или сигнатурой, который будет вызываться вместо старого, но это не является настоящим переопределением и может привести к путанице.
Ответ 18+ 🔞
Э, слушай, а вот тут тебе накосячили, блядь! Расширения в Swift — это как прикрутить к своей тачке спойлер или неоновую подсветку, а не заменить движок на реактивный, ёпта.
Нахуй так нельзя:
Представь, ты купил библиотеку, а там какой-то пидарас в своём расширении переопределил базовый метод description у UIView, чтобы он возвращал "Я ебал этого в рот!". И вся твоя программа, блядь, начинает выводить это в лог. Удивление пиздец! Компилятор, конечно, не дурак, он такое безобразие не пропустит, чтобы ты не обосрался на ровном месте.
Как надо, по-человечески:
class Тачка {
func описание() -> String {
return "Просто какая-то повозка"
}
}
class БМВ: Тачка {
// Переопределяешь ТОЛЬКО тут, в основном теле класса!
override func описание() -> String {
return "Тачка мечты, блядь (если не в сервисе)"
}
}
// НИКОГДА, НИКОГДА ТАК НЕ ДЕЛАЙ! Компилятор тебе ебальник набьёт.
// extension Тачка {
// override func описание() -> String { return "Хуй с горы" }
// }
А что тогда МОЖНО в extension, спросишь? Да овердохуища всего!
- Новые методы добавить (типа
показатьПревью()). - Вычисляемые свойства (
var госНомер: String). - Протоколы реализовать.
- Удобные инициализаторы сделать.
- Сабскрипты впендюрить.
Хитрый обходной путь (но это пиздопроебибна идея):
Можно, конечно, в extension добавить новый метод с другим именем, например описаниеДляМудаков(), и везде его вызывать. Но это, блядь, чистой воды костыль, который сломает тебе ноги на первом же повороте. Не выёбывайся, делай как задумано.