Будет напечатано Car engine started: требование протокола реализовано методом Vehicle, а Car переопределяет этот метод.
Какой вывод получим в примере №32
Будет напечатано Car engine started: требование протокола реализовано методом Vehicle, а Car переопределяет этот метод.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Рассмотрим пример, в котором протокол EngineStarter объявляет метод startEngine(). Класс Vehicle реализует этот протокол, а класс Car наследуется от Vehicle и переопределяет метод. В расширении протокола также предоставлена реализация по умолчанию. Затем создаём экземпляр Car и сохраняем его в переменной типа EngineStarter. Какой текст будет напечатан при вызове startEngine()?
protocol EngineStarter {
func startEngine()
}
class Vehicle: EngineStarter {
func startEngine() {
print("Vehicle engine started")
}
}
class Car: Vehicle {
override func startEngine() {
print("Car engine started")
}
}
extension EngineStarter {
func startEngine() {
print("Default engine started")
}
}
let car = Car()
let vehicle: EngineStarter = car
vehicle.startEngine()
Ответ
Будет напечатано Car engine started: требование протокола реализовано методом Vehicle, а Car переопределяет этот метод.
Вызов через переменную EngineStarter использует реализацию требования протокола, связанную с методом класса. Поскольку метод допускает переопределение, динамический экземпляр Car выполняет свою версию. Реализация в protocol extension здесь является лишь fallback и не заменяет метод Vehicle. Если бы Vehicle вообще не объявлял этот метод и использовал только default из extension, поведение наследника было бы другим — но это не показанный случай.