You are correct that if you are using the protocol type to interact with the instance then the method defined in the protocol extension will be called however if it is type casted to a concrete type which has a method that overrides the method in the protocol extension then the method in the concrete type would be called. This following code illustrates this:
protocol TestProtocol {
var num1: Int {get set}
var num2: Int {get set}
}
extension TestProtocol {
func doMath() -> Int {
return num1 + num2
}
}
struct MyTypeOne: TestProtocol {
var num1 = 1
var num2 = 2
}
struct MyTypeTwo: TestProtocol {
var num1 = 1
var num2 = 2
func doMath() -> Int {
return num2 - num1
}
}
var one = MyTypeOne()
var two = MyTypeTwo()
print("MyTypeOne: \(one.doMath())")
print("MyTypeTwo: \(two.doMath())")
var t: TestProtocol = two
print("TestProtocol \(t.doMath())")
The output from this code would be:
MyTypeOne: 3
MyTypeTwo: 1
TestProtocol 3
This shows that when calling the doMath() on the MyTypeTwo instance calls the method defined in the MyTypeTwo structure however if we call the method on the same instance but it being typecast as the protocol will call the method in the protocol.
For the most part we would access the types though the interface provided by the protocol however using the “is” keyword we can check if a type is an instance of a particular concrete type or use the typecast operator to downcast the instance. This would give us access to the method that is defined in the concrete type. This can certainly be useful in certain situations. I do agree that these situation should be avoided however it is something that can be done which we can not do with global functions. I was just trying to list some of the differences between protocol extensions and global functions. Honestly, and this is my personal opinion, I believe there is significant difference between protocol extensions and global functions: avoiding the global scope, using constraints, better code organization to name a couple, overriding, self parameter, better code manageability just to name some of them.
Protocol Extensions are there so we can add functionality to a group of types that conform to a specific protocol that meets any constraints defined by the extension. This allows us to avoid duplicate code similar to what we did with super classes in the OOP world. However with protocols we can create very specific protocols rather than large monolithic superclasses. Without protocol extensions we would have to revert to creating global functions however, in my opinion once again, the protocol extensions is a better option. That is what I was trying to get across.
Jon
···
On Feb 16, 2016, at 8:30 PM, Brent Royal-Gordon <brent@architechies.com> wrote:
We can override functionality provided from a protocol extension if we need specific functionality for a particular type.
No you can't. Protocol extension methods (that is, methods declared only in an extension, as opposed to default implementations, which are both declared in the protocol and defined in an extension) are statically dispatched, so calling them on the protocol witness will always use the extension's implementation, even if some concrete type conforming to the protocol has a different implementation with the same name and signature.
(I've worked on a proposal in the past that would require keywords to make this behavior clearer, but I've had trouble getting it through.)
In any case, I'm pretty sure that's what Daniel means when he says extension methods are exactly equivalent to global functions. Sure, they appear after a dot, have an implicit self parameter, and are scoped to a particular type, but there's nothing dynamic about their behavior—they're not overridable in any useful sense.
--
Brent Royal-Gordon
Architechies