Что происходит, если убрать реализацию протокола в наследнике в Swift?
Что проверяют
Понимаете ли вы, что соответствие протоколу это свойство типа, а не наследуемая обязанность, и знаете ли, откуда реализация может взяться, кроме самого класса. Вопрос с подвохом: ответа «будет ошибка компиляции» тут недостаточно.
Как отвечать
Разберите три случая.
Класс объявляет соответствие, а требование не реализовано нигде: ошибка компиляции, соответствие проверяется статически.
Соответствие объявил родитель и он же написал реализацию: наследник не обязан писать ничего, он получает её по наследству. Отказаться от соответствия наследник не может, оно приходит вместе с классом.
У протокола есть расширение с реализацией по умолчанию: код собирается, вызовется версия из расширения.
protocol Vehicle { func drive() }
extension Vehicle { func drive() { print("default") } }Отдельно скажите про диспетчеризацию. Если метод объявлен в самом протоколе, вызов идёт через таблицу соответствия и попадает в реализацию конкретного типа. Если метод живёт только в расширении протокола, диспетчеризация статическая: через переменную, объявленную типом протокола, вызовется именно версия из расширения, даже когда у типа есть своя. Это самый частый источник жалоб «мой метод не вызывается».
Ещё вариант: требование, помеченное @objc optional, можно не реализовывать вовсе, но такой протокол доступен только классам и тянет за собой рантайм Objective-C.
Где спотыкаются
Говорят «класс наследует протокол». В Swift наследуют класс, а протоколу соответствуют, и из этой путаницы рождается ожидание, что соответствие можно переопределить или снять у наследника.
Уверенно отвечают, что отсутствие реализации всегда даёт ошибку сборки, и не вспоминают ни про реализацию в родителе, ни про расширение протокола. Спрашивают обычно ровно эти два случая.
Не видят разницы между требованием протокола и методом из расширения, а потом ловят необъяснимое поведение при приведении объекта к типу протокола.