Extends (typescript)

Let’s define a base class Person that takes in a parameter name, and assigns it to a protected property.

We then create Employee that extends from Person. It has a super reference to its parent class Person. Since it extends from Person, it can access property name. In our constructor, we simply take in a name and append a Emp stamp on it. We also override the work function from parent class.

When we declare functions, we can use the base class as parameters and pass in any kind of children classes. This is called Sharing common behavior

Abstract classes

Abstract classes requires children classes to implement abstract interface.

If you extend an abstraction and do not implement it, you’ll get compiler errors:

Unlike concrete classes, abstract classes cannot be instantiated.

Hence, in order to use it

The thing about extends from either concrete/abstract classes is that it satisfies several SOLID principles:

Liskov Substitution Principle

“Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.”

Since we define valid subtypes, each implementation should work and be interchangeable as long as it implements the contract. In our case, each implementation (Employee, Manager..etc) should work and be interchangeable with parameter Person because we implement the contract.

As long as our implementation extends from our base class, any pointers or reference to base class can use our derived classes.

Dependency Inversion Principle (DIP) – Depends upon abstraction, not concretion

instead of doing:

We can make call its abstraction instead:

  • Dependency upon abstraction – Don’t depend on the concrete implementation. Rather, depend on abstraction.
  • Liskov Principle – functions with base class reference shall be able to use extended classes

plays into Open Closed Principle.

Let’s say we want to create a function that calculates the area of an array of shapes. With our current design, it might look like that:

The issue with the above approach is that when we introduce a new shape, we need to modify our calculateAreasOfMultipleShapes function. This makes it open for modification and breaks the open-closed principle.

Now that we are sure that all of our shapes have the getArea function, we can use it further.

Now when we introduce a new shape, we don’t need to modify our calculateAreasOfMultipleShapes function. We make it open for extension but closed for modification.