Мне интересно, почему следующее не распечатывает то, что, как я думаю, должно.Расширения протокола и подклассы
/* Fails */
protocol TheProtocol {
func update()
}
class A: TheProtocol {
}
class B : A {}
extension TheProtocol {
func update() {
print("Called update from TheProtocol")
}
}
extension TheProtocol where Self: B {
func update() {
print("Called update from B")
}
}
let instanceB = B()
instanceB.update()
let instanceBViaProtocol:TheProtocol = B()
instanceBViaProtocol.update()
Это напечатает следующее:
Called update from B
Called update from TheProtocol // Why not: Called update from B (extension)
Я особенно интересно, почему
instanceBViaProtocol.update()
Не выполняет обновление() в расширении на TheProtocol:
extension TheProtocol where Self: B {
func update() {
print("Called update from B")
}
}
Я бы подумал, что это будет так как B наследует от A, который принимает TheProtocol, поэтому я бы подумал, что B тогда неявно примет TheProtocol. Переход от принятия протокола к B из A дает ожидаемый результат.
protocol TheProtocol {
func update()
}
class A { // Remove TheProtocol
}
class B : A, TheProtocol {} // Add TheProtocol
extension TheProtocol {
func update() {
print("Called update from TheProtocol")
}
}
extension TheProtocol where Self: B {
func update() {
print("Called update from B")
}
}
let instanceB = B()
instanceB.update()
let instanceBViaProtocol:TheProtocol = B()
instanceBViaProtocol.update()
Результат:
Called update from B
Called update from B
Я посмотрел на https://medium.com/ios-os-x-development/swift-protocol-extension-method-dispatch-6a6bf270ba94#.6cm4oqaq1 и http://krakendev.io/blog/subclassing-can-suck-and-heres-why, но я не мог понять это. Не применяются ли методы расширения для подклассов объектов, принимающих протокол?
Изменить 'расширение TheProtocol где Self: B {' to 'extension TheProtocol где Self: A {' и посмотреть, объясняет ли это что-то для вас. –
Спасибо за подсказку. – user6902806