Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
A lot has been said about why inheritance is bad. I’ll share my take on this subject and show that inheritance is not really needed most of the time.
Structural inheritance
It breaks encapsulationInheritance for the sake of properties reuse is not the way that was meant by inheritance in OOP, since the early days of Simula and Smalltalk. Such inheritance approach breaks the human metaphor. Nobody should have an access to my internals: stomach, brain, or lungs. It breaks object’s encapsulation, its fundamental feature. It breaks OOP.
It is fragileBehavior and internal structure are orthogonal concepts. They change independently. If some object extends internal structure of another one today, it doesn’t mean things will stay the same tomorrow.
It is proceduralInheritance based on internal structure inevitably promotes procedural outlook. Good objects just have no chance to survive in such an ill environment. They become nothing but a data structures.My personal experience with huge hierarchies reflects exactly this point. One of the projects I was engaged to had a huge amount of classes representing each request that the application could handle. The terrible thing was that those classes were full of business-logic. Since there were no real objects, reflecting domain, business-logic in those request-classes was more like procedures operating upon some data. And since that inheritance was motivated solely by request-fields reuse, it was very unnatural and unmaintainable.
It often feels artificialEntities resulted from applying inheritance in this procedural sense always seem artificial. They rarely reflect ubiquitous language, if ever. The reason is that any domain has natural seams, marking off different responsibilities, behaviors — it is exactly what makes one object different from another. Objects internal data inherently can not be used to distinguish objects — just because it is internal.
Behavioral inheritance
Inheritance for the sake of behavioral extension is the way to go. It’s like biology species taxonomy. It was built relying upon some mutual traits that all of that species share. For example, all mammals are vertebrates, endothermic and produce milk to feed their babies. Primate is a kind of mammal, but have well developed hands and feet, with fingers and toes. Humans are a kind of primate, but we have the ability to self-reflect.
This is a metaphor used in object thinking and it has an interesting consequence. It implies that concrete classes can not be inherited. Keeping in mind biological taxonomy metaphor, there are no concrete mammal instances. There are no concrete primates. There are cats, dogs, humans. The real entities are the leafs of the hierarchy. All the rest is an abstract classes or interfaces. Hence what I’m in favor of is way closer to the concept of subtyping, not inheritance.
Inheritance is rare
Say we have a Merchant entity. It can be approved and expired. Typical approach is to make a “status” property. But very soon we realize that behavior differs a lot. Approved merchant can do pretty much anything that our system allows, unlike an expired one. Hence we come up with two separate classes — one for an approved merchant and one for an expired merchant. The first impel would be to make a base merchant class with all the internal data that they share — name, address, etc. But, firstly, as I wrote at the beginning, this is wrong motive, and secondly, none of object internal data has to be modeled (and often isn’t) as object’s properties. So this inheritance is wrong in both ways.
Following behavioral object decomposition approach, it turns out that inheritance is not necessary in most of the time. Things that we used to consider to be related very closely — approved merchant and expired merchant, both being merchants — in reality do not share any behavior, so do not have mutual parent.
Inheritance hierarchies are small
So following this decomposition approach there would not be huge inheritance cascades unless we design biology taxonomy. The number of decorators, on the contrary, is big.
It’s all about decomposing your domain. When done right, it comes out naturally. It’s far from being easy though.
So do not extend concrete classes—only abstract. Decompose your problem space first, this results in small and rare inheritance hierarchies, with plenty of decorators.
Implementation Inheritance Is Evil was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.