Say you have the following setup:
- A protocol named
Doablethat defines the
- A default implementation for the
doSomething()method in a protocol extension.
- A base class that conforms to
Doable, but does not implement the
- A sub-class inheriting from the base class which provides a custom implementation of the
- An array of mixed base and subclass instances that is type
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 an
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):