Member-only story
An Unexpected Behavior of Subclasses in Swift
Don’t change default param’s values when subclassing
One thing I love about my job is that it pushes me to learn something new every day. The codebase I’m working on is a mixture of various languages: I spend most of the time working on iOS-related problems, but some days I code in JavaScript, other days in Ruby, and sometimes even in Java.
The core of the framework is written in C++. I have already used C++ in the past, but never professionally. To be more effective, I decided to study it more. One of the ways I learn new concepts is by reading books, so I got my copy of Effective C++, and I started it. The book is divided into 55 independent items that can be read in any order to explore specific C++’s quirks.
This week I encountered Item 37, “Never redefine a function’s inherited default parameter value.” The reason is that an instance of subclasses uses the instance dynamic type to determine the implementation to execute (as we expect). But default parameters are statically bound. If we invoke the method on an instance whose static type is the base class, but the dynamic type is the subclass, the program will execute the subclass implementation with the base class default parameter value!
There are two reasons why C++ has been implemented in this way:
- Simplicity in implementation: the compiler doesn’t have to find a way to keep track of the dynamic type of an object and to determine the right values.
- Runtime efficiency: the compiler doesn’t have to search somewhere to get the right value.
C++ is a language that is born with very few limitations. It lets you do almost whatever you want — and with great powers comes great responsibilities. The developers are responsible for their programs working as they intended.
Swift, on the other side, is a more opinionated and evolved language. So I asked myself: how does Swift handle this problem?
My second favorite way to learn new concepts is to try them myself. So, let’s find out!
Crafting an Example
Open an Xcode playground and add these two classes:
class Base {
func greet(_…