Этот вопрос проверяет понимание механизма вызова методов и свойств, добавленных через расширения (extensions) в Swift.
Расширения в Swift используют статическую диспетчеризацию, что означает, что вызов метода определяется на этапе компиляции. Методы, добавленные через расширения, не поддерживают переопределение и привязаны к типу, а не к экземпляру.
В Swift диспетчеризация делится на два типа:
Динамическая диспетчеризация: Используется для методов классов (ссылочных типов), объявленных без final. Swift использует таблицу виртуальных методов (V-Table) для определения, какой метод вызывать в runtime.
Статическая диспетчеризация: Используется для методов, добавленных через расширения, методов структур и перечислений. Здесь вызов метода определяется на этапе компиляции.
Методы, добавленные через расширения, всегда используют статическую диспетчеризацию, даже если они добавлены в класс, а не в структуру. Это связано с тем, что расширения не поддерживают переопределение.
Пример:
class BaseClass {
func methodA() {
print("BaseClass - methodA")
}
}
extension BaseClass {
func methodB() {
print("BaseClass - methodB")
}
}
class SubClass: BaseClass {
override func methodA() {
print("SubClass - methodA")
}
}
let object: BaseClass = SubClass()
object.methodA() // Output: SubClass - methodA (динамическая диспетчеризация)
object.methodB() // Output: BaseClass - methodB (статическая диспетчеризация)Методы, добавленные через расширения, всегда используют статическую диспетчеризацию. Для гибкости и полиморфизма методы следует объявлять в основном классе, а не в расширении.