[swift-users] Protocol extension code executed instead of class code

Joe Groff jgroff at apple.com
Sat Feb 20 17:22:21 CST 2016


> On Feb 20, 2016, at 4:41 AM, Diego Sánchez via swift-users <swift-users at swift.org> wrote:
> 
> Consider the following code
> 
> protocol MyProtocol {
>     func doSomething()
> }
> 
> extension MyProtocol {
>     func doSomething() {
>         print("default impl")
>     }
> }
> 
> class A: MyProtocol {}
> 
> class B: A {
>     func doSomething() {
>         print("B impl")
>     }
> }
> 
> let a: MyProtocol = A()
> a.doSomething() // Prints "default impl"
> let b: MyProtocol = B()
> b.doSomething() // Prints "default impl" instead of "B impl"!
> 
> Now let's override doSomething in A...
> 
> class A: MyProtocol {
>     func doSomething() {
>         print("A impl")
>     }
> }
> 
> class B: A {
>      override func doSomething() {
>         print("B impl")
>     }
> }
> 
> let a: MyProtocol = A()
> a.doSomething() // Now it prints "A impl"
> let b: MyProtocol = B()
> b.doSomething() // Now it prints "B impl"
> 
> That's clearly inconsistent. I would expect to print "B impl" in the first case; or maybe always "default impl" (I highly prefer the first option)

If you don't say 'override', you're not overriding anything, but defining a logically independent method. In the first example, `doSomething` isn't really a member of `A`, so it's not overrideable by subclasses, and the declaration of `B.doSomething` just shadows the protocol extension implementation instead of overriding it. This is admittedly weird, so we do have some proposals floating to improve things by implicitly mirroring protocol methods as class methods when a class conforms to a protocol.

-Joe


More information about the swift-users mailing list