Introduce Inheritance & Object Composition
Two important aspects of the Open-Close-Principle

These days for your applications, a decoupled and encapsulated software system is ever more relevant. Reusability, maintenance, care, and sustainability play a major role in our software development projects — they are getting bigger and bigger. People, who try to master these challenges, read Robert C. Martins Clean Code, Clean Coder, or Clean Architecture. Actually, some of them follow his SOLID principles:
- Single Responsibility Principle
- Open-Closed-Principle
- Liskov-Substitution-Principle
- Interface-Segregation -Principle
- Dependency-Inversion-Principle
So, why should we care about the so called “Inheritance & Object Composition”? Because they are a big part of one of the aforementioned SOLID principles: the Open-Closed-Principle.
„Software entities … should be open for extension, but closed for modification.“
What’s more, inheritance and object composition decide about whether your software application is going to be monolithic or decoupled. We need to understand these concepts to make our software systems cleaner.
What is inheritance?
In short, inheritance describes an “is a”-relationship between 2 participants. For example, the earth is a planet, which is a celestial body. Or a cube is a geometric figure.

Facts about inheritance:
- is one of few core concepts of object oriented programming
- a subclass inherits fields and methods from their base class/superclass
- so, generally speaking, the subclass is a specialized model of its generalized base class
- properties or methods are only passed on according to their visibility (e.g. private, protected, public, …) and may be overwritten by their subclasses
- is supported by OOP — so handling is very simple
- definition at design time
- implementations can be reused in the subclasses very easily
The “Gang of Four” (Design Patterns) describe inheritance as a white-box reuse, because the internals of base classes are visible to their subclasses. And because of the strong linkage between base and subclass, the modification of the base class can affect the subclass, too. So, the base class implementation breaks up the encapsulation of all subclasses — this might be hard to change later.
This relationship is tightly coupled and entails many code risks by changing the superclass. The more a class knows about another class, the more they are coupled. Only inheritance of abstract classes can prevent this.
class Creature {
private isNatural: boolean;
protected size: number;
public beAlive(): void {
console.log('Im alive');
} constructor (isNatural: boolean) {
this.isNatural = isNatural;
}
}class Human extends Creature {
protected age: number; public setSize(value: number): void {
this.size = value;
} constructor(age: number) {
super(true);
this.age = age;
this.beAlive();
}
}class Worker extends Human {
constructor(size: number) {
super(38);
this.beAlive();
this.setSize(size);
}
}
What is object composition?
An other technique of code reuse is object composition. In short, it describes a “has a”-relationship between 2 or more participants. For example, a car has got wheels, an engine, windows, doors, and a lot of electronic stuff.

Facts about object composition:
- is fundamental to every programming language (not only OOP)
- it’s an assignment of a reference to other objects
- it can be accessed by interfaces (Dependency Inversion)
- you can change this assignment whenever you want — so this runtime behaviour allows replacing different objects of the same type dynamically
- definition at runtime
The “Gang of Four” (Design Patterns) describe Object Composition as black-box reuse, because you can’t see the internal code — only the interface.
This loosely coupled concept and the interface-access allow more flexibility in code design, secure Uncle Bobs Open-Closed-Principle, and lead to encapsulation. Because your existing and working code will not be altered while you can still add new behaviour — you can change components and objects without any code risks and without having to think about code dependencies.
Besides, using object composition is a good method to mock test data.
interface AbstractEngine {
howMuchIsIt(): void;
}class DieselEngine implements AbstractEngine {
private cycle: string;
private compressionRatio: string; public howMuchIsIt(): void {
console.log('High initial and maintenance costs');
} constructor() {
this.cycle = 'Diesel';
this.compressionRatio = 'high';
}
}class PetrolEngine implements AbstractEngine {
private cycle: string;
private sounds: string; public howMuchIsIt(): void {
console.log('Low initial and maintenance costs');
}constructor() {
this.cycle = 'Otto';
this.sounds = 'Brumm brumm..';
}
}class Car {
public engine: AbstractEngine;
public drive();
}function buildCar(engine: AbstractEngine): Car {
const result: Car = new Car();
result.engine = engine;
return result;
}function buildCarWithPetrolEngine(): Car {
const result: Car = buildCar(new PetrolEngine());
result.howMuchIsIt(); // Low initial and maintenance costs
return result;
}function buildCarWithDieselEngine(): Car {
const result: Car = buildCar(new DieselEngine());
result.howMuchIsIt(); // High initial and maintenance costs
return result;
}
What to prefer: Inheritance or Object Composition?
The “Gang of Four” write in Design Patterns, you should prefer composition over inheritance whenever you can, because of the decoupled principle.
Both have got strengths and weaknesses, but most developers instinctively opt for inheritance. Maybe they learnt it through their education and gained more experience than with composition. Personally, I am using object composition more than inheritance.
What you prefer depends on your problem. Most UI frameworks are based on inheritance (e.g. WinForms in C#). On the other hand most Design Patterns use object composition.
Object composition in action: Abstract Factory
Usage:
- to configure a system of many object families
- to provide a class library, which can be accessed by interfaces
- to enclose creation and composition of objects
- to force the system to use a family of related objects
Example for creating a theme feature:
Conclusion
These days it’s very important to design our software applications more decoupled and encapsulated. Object composition is a concept to reuse code more flexibly. Inheritance is better known and easier to handle. Also, you can combine both concepts. I started to use object composition more often after reading the book “Design Patterns”. I learnt it is very important to build your software system in an easily maintainable way. We should try to be DRY and reuse our code.
Design Patterns are great and it is fun to code them — object composition is a big part of it. Besides, you learn other coding techniques — for me, I now better understand Angular with its own art (Dependency inversion, observables, states, etc). It’s worth to take a look at them. Try it out!
Thank you and Happy Coding! :)