Определение вызываемого метода в иерархии протоколов

Вызов TestClass2().test() выбирает наиболее специализированное расширение C2 и печатает C2.

Короткий ответ

Что ответить на собеседовании

Вызов TestClass2().test() выбирает наиболее специализированное расширение C2 и печатает C2.

Подробный разбор

Ответ с пояснениями

Условие

В задаче рассматривается ситуация, когда несколько протоколов наследуют друг друга и каждый из них имеет собственную реализацию метода test() в расширении. Нужно понять, какая именно реализация будет выполнена при вызове метода у экземпляра класса, который одновременно соответствует нескольким из этих протоколов.

protocol A2 {
    func test()
}

protocol B2: A2 {
    func test()
}

protocol C2: B2 {
    func test()
}

extension A2 {
    func test() {
        print("A2")
    }
}

extension B2 {
    func test() {
        print("B2")
    }
}

extension C2 {
    func test() {
        print("C2")
    }
}

class TestClass2: A2, C2, B2 {}

TestClass2().test()

Ответ

Вызов TestClass2().test() выбирает наиболее специализированное расширение C2 и печатает C2.

C2 наследует B2, а B2 — A2, поэтому требования образуют цепочку уточнения, а не три независимых конфликтующих протокола. TestClass2 соответствует C2 и тем самым также его предкам. При выборе доступной default-реализации C2 является наиболее конкретным вариантом. Явное перечисление A2 и B2 в объявлении класса здесь избыточно. Не следует переносить этот ответ на несвязанные протоколы с одноимёнными методами: там может возникнуть неоднозначность.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее