Codementor Events

Composition vs Inheritance. Aryan learns about Composition | by Adi Sahai | Medium

Published Jan 17, 2024
Composition vs Inheritance. Aryan learns about Composition | by Adi Sahai | Medium

Aryan was logging in after a vacation. He had to take his mind off things. He had just been to visit his parents for two weeks. Mom had pushed him to get married soon, which had irritated him. They had a shouting bout about it. Aryan's dad tactically avoided the skirmish and buried his head in a book. He had also resisted all attempts to get pulled into the flight. Finally they came to a compromise. If Aryan could create an account on a matrimonial website, his mom would get off his back. He would not have to talk to anyone for a few months.
He was checking his mail when he noticed that a pull request he had submitted just before leaving on vacation had a few comments on it, by a senior engineer on the team, Josh. This further irritated Aryan. He had desired to move fast and merge as many changes as possible. He was new to the company and wanted to get noticed for swiftly tackling large projects.

He had always considered numbers (number of merged PRs) to be a useless metric to track programmer productivity but ever since the firings at Twitter and the fast approaching doom of a recession, he wanted to make sure that his "numbers" were up to the mark. He had been working on this PR for a while now. It was a big change and he was really hoping to merge it so that he could work on the next item.
He looked at the comment,

I wonder if it would better to use composition here instead of inheritance. The only use of inheritance here seems to be for the sake of reuse of code, however, you could use composition for that and not have multi level inheritance.

What the hell is composition now? Aryan had been in the industry now for 5 years and he was pretty sure he knew most things. What could be composition thing this guy was talking about? Grudgingly, he replied to the comment, "Thanks for the suggestion, I'll take a look and update the PR accordingly". He added a task to this todo,

Composition vs Inheritance???

Later that day, after finishing the meetings for the day and having a tasty plate of take-out biryani, Aryan finally had a few hours of maker time available to him. He started diving into his Java reference books. Here are his notes,


Composition vs Inheritance

I want to inherit from an abstract class, Vehicle. There are multiple such subclasses that need to be written, Camry, Ninja and Civic Type-R (manual gear shift). All these subclasses are only marginally different, with a lot of code that can be extracted for reuse.

public class Vehicle {
// Super class functionality
    public void drive(Road road, Wheels wheels);
}

public class Camry {}
public class Ninja {}
public class CivicTypeR {}

Here is how I initially wrote it,

public class Vehicle {
// Super class functionality
    // drive vehicle here
    public void drive(Road road, Wheels wheels) {
        // default driving logic for automatic vehicles
    }
}

public class GearBox extends Vehicle {
    public void driveUtil(Road road, Wheels wheels, Gear gear) {
        // driving logic here, for vehicles with gear
    }
}

public class Camry extends Vehicle {
    // use default logic
}

public class Ninja extends GearBox {
    // override 
    public void drive(Road road, Wheels wheels) {
        // custom gear changing logic specific to Kawasaki Ninjas
        return driveUtil(road, wheels, gear);
    }
}

public class CivicTypeR extends GearBox {
    // override 
    public void drive(Road road, Wheels wheels) {
        // custom gear changing logic specific to manual Civic Type Rs
        return driveUtil(road, wheels, gear);
    }
}

What is Composition?

Composition is way to implementing a "has-a" relationship instead of "is-a" relationship which is what inheritance is for. It is an approach to add functionality to a given class without the hassle of coming up with a large and custom class which should account for all possible future use cases.

Composition is safer (in certain cases)

In the case above, if tomorrow, Toyota adds a flying gear to it's Camrys, then if we add a flying functionality to the super class GearBox, we'd have by default added a flying functionality to all subclasses which inherit from GearBox. But we can't have flying Ninjas right?
So instead, we can choose to use composition and add a fly method to GearBox and have a GearBox object in each of the subclasses of Vehicle.

// Super class functionality
    // drive vehicle here
    public void drive(Road road, Wheels wheels) {
        // default driving logic for automatic vehicles
    }
}

public class GearBox {
    public void drive(Road road, Wheels wheels, Gear gear) {
        // driving logic here, for vehicles with gear
    }
    
    public void fly() {
        // fly away logic
    }
}

public class Camry extends Vehicle {
    GearBox gearBox;
    
    public void fly() {
        gearBox.fly();
    }
}

public class Ninja extends Vehicle {
    GearBox gearBox;

    public Ninja() {
        this.gearBox = new GearBox();
    }

    // override 
    public void drive(Road road, Wheels wheels) {
        // custom gear changing logic specific to Kawasaki Ninjas
        return gearBox.drive(road, wheels, gear);
    }
}

public class CivicTypeR extends Vehicle {
    GearBox gearBox;
    
    public CivicTypeR() {
        this.gearBox = new GearBox();
    }
    
    // override 
    public void drive(Road road, Wheels wheels) {
        // custom gear changing logic specific to manual Civic Type Rs
        return gearBox.drive(road, wheels, gear);
    }
}

This might not seem like a huge issue if you control code for all the classes here. But if GearBox was maintained by a third party or it was in a different package and one chooses to inherit from it, one would have to keep track of changes made to GearBox, lest one would have unknowingly added flying capabilities to all your vehicles. That just sounds tedious.
If you use composition, then you don't have to worry about new functionality being added to GearBox. They could add a gear to teleport of all you care, and your Ninja would still be where you left it.
I was using inheritance for the wrong reasons. Ninjas and CivicTypeRs are not GearBox, which specifies a "is-a" relationship. Instead, they have a GearBox which in turn specifies a "has-a" relationship which is the correct use case for Composition.
However, composition is not always the answer. When you have a genuine "is-a" relationship then consider using inheritance. So, in this case, if we had to implement a Corolla as well, then we would be completely within our rights to add a ToyotaCars class and extend in Corolla and Camry. Both Toyota cars would have similar functionalities and it would a good idea to extract that out to ToyotaCars and keep the cars lighter.


Aryan, looked at this watch. A few hours had passed. This topic was interesting to say the least and he had enjoyed learning after a while. He updated is pull request and closed this laptop.
He picked up his phone, which he had not checked for a while now. There was a few emails, a few push notifications and one ominous message from his mom,

Did you create your profile?


References:

Effective Java 3rd Edition: Item 18
Design Patterns
Geeks for Geeks article on Composition
Geeks for Geeks article on Inheritance
Encapsulation - definition & overview | Sumo Logic
Geeks for Geeks article on Favoring Composition over Inheritance
Composition vs Inheritance: How to Choose? | Thoughtworks
Inheritance vs. Composition. And which should you use? | by brian | Better Programming


Discover and read more posts from Adi Sahai
get started
post commentsBe the first to share your opinion
Israr Keerio
3 months ago

However, I can certainly provide information on the topic of “Composition vs Inheritance” if you’re interested.

Composition and inheritance are two fundamental concepts in object-oriented programming (OOP) that describe how classes and objects can be related to each other.

Inheritance:

Definition: Inheritance is a mechanism where a new class (subclass or derived class) inherits properties and behaviors from an existing class (superclass or base class).
Advantages: It promotes code reusability by allowing a class to use the properties and methods of another class. It establishes an “is-a” relationship between the subclass and superclass.
Composition:

Definition: Composition is a concept where a class is composed of one or more objects of other classes. Instead of inheriting their properties and behaviors, the class uses instances of other classes to achieve its functionality.
Advantages: It promotes flexibility and reusability by allowing you to change the behavior of a class by changing the composition of objects. It establishes a “has-a” relationship between the containing class and the contained classes.
In many cases, composition is favored over inheritance because it tends to lead to more flexible and maintainable code. With composition, you can build complex systems by combining simple, well-defined components, reducing the dependency on a specific class hierarchy.

If you have specific questions or if there’s a particular aspect of composition or inheritance you’d like more information on, feel free to ask! CHECK:https://hindisuno.com/ayatul-kursi-in-hindi/

Show more replies