Swift protocol extensions 101

Protocol extensions in particular, which are at the core of whole concept, are neat and abstract and complex, and my brain hurts a little when I think about it. But the thing is, it is not that difficult to wrap your head around them.

Consider a protocol:

Swift

1

2

3

4

protocolBehaviour{

funcmethodA()

funcmethodB()

}

Now, we have two classes that implement that protocol:

Swift

1

2

3

4

5

6

7

8

9

10

11

classClassA: Behaviour{

init(){

print("classA initializer")

}

}

classClassB: Behaviour{

init(){

print("classB initializer")

}

}

But we want them to implement it with a little twist. We want ClassB’s implementation of method B to be a little bit different.

So we can start with a default implementation of the protocol, in a protocol extension:

Swift

1

2

3

4

5

6

7

8

9

extensionBehaviour{

funcmethodA(){

print("methodA in default extension")

}

funcmethodB(){

print("methodB in default extension")

}

}

And now an extension to that protocol that will only be aplicable to instances of ClassB

Swift

1

2

3

4

5

extensionBehaviour whereSelf: ClassB{

funcmethodB(){

print("methodB in specific to class B extension")

}

}

And if we do this:

Swift

1

2

3

4

5

6

7

8

leta:Behaviour=ClassA()

letb:Behaviour=ClassB()

a.methodA()

a.methodB()

b.methodA()

b.methodB()

We get this trace:

Swift

1

2

3

4

5

6

classA initializer

classB initializer

methodA indefaultextension

methodB indefaultextension

methodA indefaultextension

methodB inspecific toclassBextension

Boom.

Final words

Now, consider the second extension, the one I called ExtensionToClassB. What if, instead of applying that extension to a class type, I apply it to another protocol?