Composition vs Inheritance
Tags: programming, javascript, typescript
Published: 2021-06-26 12:14:42

I recently completed an online course and these are my takeaway from Composition and Inheritance.

## Inheritance

With inheritance we can extend the functionality of an existing class by overriding its method in a Child class e.g

```
class Parent {
  function sayHi() {
    console.log("sayHi from Parent");
  }
}
class Child {
  function sayHi() {
    console.log("sayHi from the Child");
  }
}
```

Inheritance is characterised by an "is-a" relationship between two classes e.g Apple is Fruit, Car is a Vehicle etc. Inheritance is suited for use cases where there is tight coupling between the classes which is rarely the case in the real world.

Lets say your are building a house and you need to model a window in code. So you might come up with following:
```
class Window {
  height: number;
  width: number;
  open: boolean;
  toggleOpen() {}
  area(){}
}
```
The properties are self explanatory. Pay attention to the `area` method. It calculates the area.
Now in addition to window we also want to add a `Wall`. The code for the wall might look as follow.
```
class Wall {
  height: number;
  width: number;
  color: string;
  area() {}
}
```

You see that they share some common properties so you use inheritance for code reuse. You come up with class named `Rectangle` which has common properties from the both of the classes.

```
class Rectangle {
  height: number;
  width: number;
  area() {}
}

class Wall extends Rectangle {
  color: string;
}

class Window extends Rectangle {
  open: boolean;
  toggleOpen() {}
}
```
So according to this code `Wall` is rectangle and `Window` is also a rectangle, now let's suppose the we want to introduce new type of window called circle window. 

Circle window can not extend from `Rectangle` window because it does not make sense. Now this is a type of Window so you might be tempted to inherit from the window class but window class itself inherits from `Rectangle` so although it can be extended but it will also inherit the methods from `Rectangle` class which does not make sense and it as it is derived from `Rectangle`.

>You wanted a banana but what you got was a gorilla holding the banana -- Joe Armstrong

So an other way is be to create a new Circle class and extend from it. It might seem a nice idea initially but as the application grows we might encounter again a similar situation. I will show on later how we can resolve this via composition. 
```
class Circle {
 radius: number;
 area(){}
}

class CircleWindow extends Circle {
  open: boolean;
  toggleOpen() {}
}
```
## Composition
For this I would quote the following text from GoF Design Patterns Book

>Object composition is an alternative to class inheritance. Here, new functionality is obtained by assembling or composing objects to get more complex functionality. [...]  Object composition is defined dynamically at run-time through objects acquiring references to other objects

To recap, composition is an alternative strategy to class Inheritance for code reuse. In composition a class will have reference to another class instance as its memeber variable. Lets see this with an example. I will change the example in the last section. 
```
interface Shape {
 area(): number;
}

class Wall {
  color: string;
  area(){}
  dimensions: Shape;
}

class Window {
  open: boolean;
  toggleOpen(){}
  area(){}
  dimensions: Shape;
}
class Rectangle implements Shape {
  height;
  width;
  area(){}
}
class Circle implements Shape {
  radius;
  area(){}
}
```
So in this example inside  `Wall` and `Window` we have a member variable called dimensions, which is of type Shape. The interface `Shape` guarantees us that their will be always a method named `area` present. So now we both `Window` and `Wall` can accept any object for its memember variable dimensions as long it satisfies the interface `Shape`, in a way we have delegated the responsibility for calculating the area to the class `Rectangle` and `Circle`

## Inheritance vs Composition
So this was a quick recap of inheritance vs composition. This is very difficult to explain topics but with time you develop instincts for this. Now lets take a look at `Abstract` class and `Interface`. These are features provided by programming languages to aid in inheritance and composition.

## Abstract Class
`Abstract` classes are classes for which you create an instance of them. They maybe used to provide a default implementation in case the overriding classes does not provide one. In javacript you can create an abstract class by adding the keyword `abstract` infront of the class.
```
abstract class Destroyer {
  onDestroy() {
    db.close();
    analytics.send("Database Closed);
  }
}
class MyDestroyer extends Destroyer {
}
The class MyDestroyer gets the implemntation defined in class Destroyer.
```

## Interface
`Interface` are used to define set of properties that must exist on class. Interface only contains what a class implentating that interface should have it does not dictate what it should do. Interface are loosely coupled compared to Abstract classes and are usually favoured.

In next part of the article I will show an example of inheritance and how to convert it into composition along with use of `abstract` and `interface`. stay tuned!🙂 

P.S: if you find any mistakes please let me know in comments. Design Patterns are difficult to understand and even harder to write about.