Pay To Keep Playing

Why pay once when you can pay to keep playing? While more and more Massively Multiplayer games are moving away from a subscription based revenue stream, more and more single-player and multi-player…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Inheritance and Composition

We developers try to reuse the logic as much as possible. One way to do that is inheritance and the other is composition.

Inheritance: Inheritance is when a subclass inherits its properties from a designated parent class. It’s like clay modeling. You get an existing clay model of something and you put more clay on top of it to give it the desired shape. Composition: Composition is when a class is composed of its properties. It’s like you get some lego blocks and join them to create a shape of your liking.

Let’s try to understand the differences between the two with a class design problem.

We have two classes for ducks and pigeons, and they share fly() and hitAircraft() (sometimes they fly near the airport and hit aircraft) methods. This is code duplication and every time we have to change the fly() method we have to change it at two places, which is completely unacceptable. So we will refactor the code, using inheritance, something like this:

Now to make things interesting, let’s assume that these birds have entered the airspace of an airport and they are pooping everywhere and are flying into the engines of the aircraft. So, the airport employs the cleaners and shooters to take care of the birds. Then, our class diagram will grow something like this:

Everything was in perfect balance in our little airport universe until the court decided to ban shooting at the airports for the obvious reasons. Now that balance is in danger. To restore the balance, the airport decided to employ hawks to chase and kill other birds. For that, we have to create a Hawk class with three methods chaseBirds(), killBirds() and fly().

Now things get interesting, how can we model the Hawk class with the current classes. An easy way to do it is to copy the fly() method.

Now we have duplicated the fly() method in the Hawk and the Bird class, which is unacceptable. So, we will try something else.

Another solution is to create a new parent class and define all the common attributes in that class. Since everything is in the context of an airport. Let’s create a new grandparent class Airport.

This works, but it is not flawless. The Cleaner class inherits fly() method even when it can’t fly. Furthermore, every time Hawk has to inherit another bird attribute, we have to lift it to the Airport class and like a side effect, the Cleaner class will also inherit that attribute. As we can see, it is turning into the gorilla-banana problem. You wanted a banana but instead, you got a gorilla holding a banana in a jungle. Can we do better?

No points for guessing, we can do better with composition. We will separate all the bird attributes in the two groups, ‘hawk & bird’ attributes and ‘non-hawk bird’ attributes.

Instead of inheriting the common bird attributes from a parent class, we are composing the bird attributes from the two groups we defined earlier. This solves the issues we were facing when we were using inheritance.

The problem with the inheritance is that it forces us to fix the hierarchy of objects, early in the design. As the program evolves, this coupling increases and it becomes harder to introduce even minor changes. In our example, just to give the Hawk the ability to fly we had to introduce a new class and had to change a couple of existing classes.

On the other hand, composition allows us to inherit properties without the side effects of inheritance. In our example, after using composition, the Cleaner class doesn’t inherit the fly() method anymore. Furthermore, in the future, if the Hawk has to access another common bird method, we just have to move that method from NonHawkBirdAttr() to HawkandBirdAttr().

A lot of people argue that if there is an is-a relationship then you should use inheritance and if there is a has-a relationship then you should use composition. It sounds logical at first, but soon you realize that you can come up with both the relationships for any given problem. A car is a vehicle, but it also has an engine, brakes, and wheels. So, it can be modeled as a subclass to parent Vehicle class or it can be modeled as a sum of its parts using composition.

I don’t see a reason to use inheritance when you can just use composition. If you only have a few objects ( shallow hierarchy ) and you know that requirements will not change in the future i.e. your class hierarchy will remain intact ( which will never be the case ), then you can go for inheritance.

Thanks for reading the article. 👋

Add a comment

Related posts:

How to use Content Blocker Extension?

Content Blockers are app extensions that you build using Xcode. They indicate to Safari a set of rules to use to block content in the browser window. Blocking behaviors include hiding elements…

To dismiss God

To dismiss God. Man will say or ask; why did He let this happen. Where was He when this happened? Why didn’t He stop it if he’s loving and knows everything? This happens on a micro-level. To achieve…

LRHSD holds fourth and final strategic planning forum

Despite snowfall earlier in the day and bitterly cold air after sunset, students, staff, families and stakeholders of the Lenape Regional High School District packed the cafeteria at Lenape High…