Мое намерение в исходном коде, из которого я извлек мой пример, состояло в том, чтобы протокол предоставил некоторые реализации по умолчанию для ряда абстрактных классов и при необходимости переопределил их в иерархиях ниже этих классов. Однако это не go, как планировалось.
Вот базовый код (взятый с игровой площадки, где я уменьшил исходный код до сути проблемы):
// protocol and default impls.
protocol MyProtocol {
func hello()
}
extension MyProtocol {
func hello() { print("hello from default in protocol extension") }
}
// Class hierarchy
class AbstractParent: MyProtocol {}
class Child: AbstractParent {
func hello() { print("hello from child") }
}
(Child() as MyProtocol).hello()
Child().hello()
Запустив это, я ожидал увидеть:
hello from child
hello from child
Но вместо этого получил:
hello from default in protocol extension
hello from child
Для меня имеет смысл, что, поскольку первый вызов выполняется из преобразования Child
в MyProtocol
, он вызывает функцию протокола, даже если функция существует в Child
, потому что во время компиляции она видит только MYProtocol
.
Однако ...
Если я переключаю абстрактного родителя в значение по умолчанию реализация, подобная этой:
// protocol and default impls.
protocol MyProtocol {
func hello()
}
extension MyProtocol {
func hello() { print("hello from default in protocol extension") }
}
// Class hierarchy
class AbstractParent: MyProtocol {
func hello() { print("hello from abstract parent") }
}
class Child: AbstractParent {
override func hello() { print("hello from child") }
}
(Child() as MyProtocol).hello()
Child().hello()
Теперь я получаю ожидаемое поведение:
hello from child
hello from child
Теперь, хотя мы все еще приводим к MyProtocol
, он видит реализацию в Child
.
Кто-нибудь может объяснить, почему добавление реализации к абстрактному родительскому классу делает эту работу?