The Inheritance Curse
Once upon a time, in a kingdom, not really far away, there was an evil queen. Her name was NSObject. To look nice, she was giving to her people lots of gifts. But the biggest treasure she was offering them was code reuse.
This code reuse was achieved through inheritance… from the queen! And thanks to this, the queen was keeping control over all her people for generations, and generations, and generations…
The evil queen was in control of her kingdom for several decades, when one day, came… a swift wizard. His name was Christobal but he is better known in Australia as the clang guru.
The wizard wanted to create a new kingdom next to the queen’s kingdom.
To do this, he brought with him different kind of people: classes, structs and enums.
When the queen heard about his project, she sent a curse to the wizard.
Thankfully the wizard was strong and only the classes got infected by the inheritance curse.
The war between the two kingdoms continued for several years until one day… the wizard left!
So it is now our duty to continue the fight and to do this, let’s see the rules to win.
In the wizard kingdom, you might need to work with those infected classes for several reasons. Maybe you work with UIKit, or you want a reference type, or simply you want to reuse some code.
If you work with UIKit, you’re doomed. At some point, you will have to inherit from one of the UIKit classes which means that you will have to inherit from the queen! But you can stop the propagation of the curse by using the final keyword.
You might need a class because you want a reference type and not a value type so you can have something that can be accessed from different places. In this case, you don’t have to inherit from the queen. But still, you must stop the spread of the curse by using, once again, the final keyword.
Finally, you might be using a class so the code you’ll put in it can be reused in its subclasses. If it is what you are doing, stop right there! There is lots of other tools at your disposal when it comes to code reuse.
And in almost every cases, those tools will be better than inheritance.
To sum up: always mark your classes final or… don’t use a class.
And together, let’s keep fighting the evil queen until we get rid of the inheritance curse!
This is the transcript of a lightning talk I gave at dotSwift ’17 in Paris and at PlaygroundsCon ’17 in Melbourne.
I still use inheritance every day, as I work with UIKit. But, for more than a year now, I mark each and every class I write final so it cannot be subclassed. It allows some compiler optimisations, and it makes code more consistent by removing features that can be achieved in a more swifty way: code reuse with protocol extensions, generics or composition and polymorphism with protocols.
I am wondering if Chris Lattner would have implemented inheritance in Swift if it didn’t had to be Objective-C compatible… 🤔 And now, I know he would 😭 https://twitter.com/clattner_llvm/status/848212109032775680