Say you have the following setup:
- A protocol named
Doable
that defines thedoSomething()
method. - A default implementation for the
doSomething()
method in a protocol extension. - A base class that conforms to
Doable
, but does not implement thedoSomething()
method itself. - A sub-class inheriting from the base class which provides a custom implementation of the
doSomething()
method. - An array of mixed base and subclass instances that is type
[Doable]
.
The results of invoking doSomething()
on all elements of the array may surprise you. When the for loop / reduce / whatever invokes doSomething()
on a member of the array which is a subclass, you will not get the subclass’ custom implementation. Instead, you will get the default implementation!
When the runtime goes looking for doSomething()
on the current object (of type Doable
) in the loop, it looks to the object which actually conforms to the Doable
protocol, which is the base class. The runtime checks to see if the class implements the method, and when it sees that the base class does not, it falls back to the default implementation, rather than seeing if the subclass implements it. Apparently, the subclass is only checked in instances where it is overriding a method explicitly defined on its superclass.
So, the solution is actually quite simple:
- Provide an implementation of
doSomething()
on the base class. It can just be a duplicate of the default implementation, if that’s the behavior you want for it. - Change the subclass’
doSomething()
implementation to include anoverride
declaration.
That’s it! The next time you run your loop, the sub-class will have it’s doSomething() method called. I made a playground for you to check this out (turn on documentation rendering):
[gist https://gist.github.com/JoshuaSullivan/0752d008e1aa08febdd18c25954183d7]