Composition vs inheritance refers to two major concepts in object-oriented programming (OOP). They are building blocks of OOP and both work to model the relationship between two classes so that it’s easier for programmers to write reusable code.
Composition vs inheritance refers to how each of these concepts can help programmers reuse code. Reusable code is the use of existing software to build new software by adhering to the principles of reusability.
Code reusability is a primary productive functionality in IT and it is achieved by establishing relationships between classes of objects via composition vs inheritance.
The difference between inheritance and composition is that classes and objects in inheritance code are tightly coupled, meaning that they should not be changed because changing the parent or superclass risks changing the sub-class, or child class, thus breaking your code.
In composition, on the other hand, classes and objects are loosely coupled, meaning you can more easily switch up these components without breaking the code.
This tends to make the composition more flexible, so many developers believe it to be superior to inheritance - but this is oversimplifying the matter.
Let’s take a closer look at how these two concepts work and the benefits of using composition vs inheritance.
Inheritance, along with abstraction, encapsulation, and polymorphism, is one of the four primary concepts in Object-Oriented Programming.
Inheritance means a class can inherit the fields and methods of its superclass.
In other words, a new class can use by default the fields and methods from an abstract class that inherits from another class, etc., all the way down different classes to the base class.
You can liken the inheritance hierarchy to a family line. A child inherits the characteristics and behaviors of one or more objects. The derived class usually has an “is a” relationship to the base class.
The inheritance relationship is a way to reuse code that was already written in java programming. In these examples, Samsung is a subclass of the Mobile base class.
You can derive from Mobile to create a Samsung class and you can derive from Samsung to create a Samsung S22 class. So, the interface and implementation of the base class Mobile are inherited by the subclass Samsung.
This example is known as Hybrid inheritance, and here are other types of inheritance;
Composition is an alternative to the class inheritance that serves different purposes. In composition, the models have a “has a relationship” (see the second illustration). It lets you create complex types by combining behaviors and characteristics of other types.
In a class created with composition, there is a composite side, which is a collection of component instances, and a component side, which are the instances the composite class will contain.
A composite class can contain a range of component instances. Using the example above, the Horse class can be composed of a component class Mane. The relationship would be “Horse has a Mane.”
You might have a Lion class that could also leverage the functionality of the already existing Mane class without needing to derive one class from the other.
The primary issue in composition vs inheritance is that the programming world has begun to think of these two concepts as competitors. Like everything in software development, there are use cases for each and trade-offs to make for choosing one over the other.
Composition is fairly simple and easy to understand. Everything we see is a composite of different parts, i.e. a dog with legs and a tail, a landscape with ocean and sky, etc. The purpose of composition is to make wholes out of parts.
Inheritance, on the other hand, is an abstraction. The definition is simple but it can quickly become complex and confusing when used to liberally. The purpose of inheritance is a little more complicated - to understand it better it is helpful to look at the purposes it serves, semantics, and mechanics.
Inheritance creates meaning, or semantics, in a hierarchy of classifications. Arranging attributes from more general to more specific and grouping related attributes together into subgroups. The semantics of a class are mostly created in its interface, i.e. the set of messages that the class responds to.
But some of the semantics also live in the set of messages sent by the class. When inheriting from a class, you accept ownership for all the messages the base class sends on your behalf as well as the messages it can receive. In other words, the sub-class is very tightly coupled to the base class.
In composition, this isn’t the case because the sub-class is only using an instance of the base class as a component instead of inheriting sets off attributes from the entire family tree.
Inheritance creates mechanics by encoding the fields and methods of a class in order to make it reusable and augmentable in subclasses. The subclass inherits the implementation of the base class along with its interface.
Thus, changing the code in a base class can lead to unwanted side effects on the subclasses underneath it - or possibly even across the entire codebase.
The most common and best practice use of inheritance is for differential programming. If you need a widget that is just like your existing widgets except for a few small changes, Inheritance will save you tons of time because you can reuse the entire interface and implementation from the base class.
However, if the subclass is removing things that exist in the base class, inheritance will cause problems. You can enhance a base class derivative, but you can’t remove anything from it.
Composition vs inheritance isn’t a black and white issue. There are times when it’s best to use one and times that call for the other.
Thus, the main difference between composition vs inheritance is in the relationship between objects. Inheritance offers a way to reuse code by extending a class easily and with little effort. It is a valuable tool for establishing relationships between classes.
In situations where you want to use an object as a field within another class, you should use composition.
It offers a way to use the object without disrupting the internal details of that object. If the subclass inherits several fields it will never use, it becomes too confusing and hard to maintain and should instead be written with composition.
Choosing composition vs inheritance can sometimes be tricky. If you need help getting on the right track, improving the quality of your production code, or launching your next project without the need to rewrite it later, Adservio can help.
Our team of code quality experts can assist your business in writing clean and effective code with every project. Contact us to learn more.