Protocol Extensions and Subclasses

I am wondering why the following does not print, what I think it should be.

/* 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()

This will print the following:

Called update from B
Called update from TheProtocol // Why not: Called update from B (extension)

I am particularly interested in why

instanceBViaProtocol.update()

Does not update () in the extension in TheProtocol:

extension TheProtocol where Self: B {
    func update() {
        print("Called update from B")
    }
}

I would have thought that since B inherits from A, which accepts TheProtocol, so I would have thought that B would then implicitly accept TheProtocol. Moving protocol adoption to B from A gives the expected result.

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()

Result:

Called update from B
Called update from B

I took a look at https://medium.com/ios-os-x-development/swift-protocol-extension-method-dispatch-6a6bf270ba94#.6cm4oqaq1 and http://krakendev.io/blog/subclassing-can-suck- and-heres-why , but I could not figure it out. Are extension methods applied to subclasses of objects that accept the protocol?

+4
1

+ Swift.

- , , . Swift 3 .

, . TheProtocol.

let instanceBViaProtocol:TheProtocol = B()
instanceBViaProtocol.update()

, . . , , B. Swift, .

Swift , . , B update() Witness TheProtocol. TheProtocol, .

. , , , . , .

protocol TheProtocol {
    func update()
}

class A: TheProtocol {
    func update(){
        print("Implementation of A")
    }
}

class B : A {
    override func update(){
        print("Implementation of B")
    }
}

//All those who conform to TheProtocol will execute this.
extension TheProtocol {
    func update() {
        print("Common: TheProtocol")
    }
}
extension TheProtocol where Self: B {
    func update() {
        print("Common: TheProtocol for B's")
    }
}
extension TheProtocol where Self: A {
    func update() {
        print("Common: TheProtocol for A's")
    }
}


let instanceBViaProtocol:TheProtocol = B() //It prints "Implementation of B"
instanceBViaProtocol.update()

, .

https://www.raizlabs.com/dev/2016/12/swift-method-dispatch/ swift.

, .

0

Source: https://habr.com/ru/post/1659886/


All Articles