Inheritance- Object Oriented Principles in Typescript

Writing Better Typescript Applications

Raymond Johnson
7 min readFeb 5, 2019

Preface

This writing belongs to a series of articles that I was inspired to write entitled Object Oriented Principles in Typescript. This series is meant for beginner programmers who want to become experts at their craft or intermediate programmers who want to get a more sound understanding on the foundational principles about writing code and here we’ll be starting at the core of one of the most popular programming paradigms, OOP. If you haven’t read part two of this series on abstraction, I highly recommend it as we will be picking up where we left off and will be implementing the new features of our big update that our stake holders have been brewing up, all while understanding today’s topic inheritance! Welcome to part three of Object Oriented Principles in Typescript!

What is Inheritance?

The easiest way for me to define inheritance is, “the process of structuring a class hierarchy of similar objects that can extend the general functionality of it’s base while making it’s own implementation more concrete.”

Even the definition that I made up myself still may leave new comers a bit gloomy about what inheritance actually is, so here’s a definition off of Wikipedia that may help with your understanding.

In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object (prototype-based inheritance) or class (class-based inheritance), retaining similar implementation.

Base Class and Sub Class Relationship

When breaking down the different parts of inheritance, think in terms of base classes and sub classes, With sub classes being the objects preforming the action of extending while base classes are the objects being extended. Think of sub classes as having an IS-A relationship to its base class.

Quick Example

A very common example to illustrate inheritance is talking in terms of animals. Take a dog, cat, and bird for example. What do they have in common? Well, they’re all animals. So it would be beneficial to our application to generalize some of the common animal actions such as eating, walking, and making sounds into a common base class named animal that the dog, cat and bird can all extend because they all have an IS-A animal relationship. Then inside of the dog, cat and bird classes, we can go ahead and make their implementations more concrete, for example defining their makeSound() method around the actual sounds that those specific animals make. In this case, dogs bark, cats meow and birds chirp.

Bringing Our Stakeholders Dreams To Life!

Photo by rawpixel on Unsplash | Hopefully they look this happy after we’re finished at the office today 😅

Gathering Project Requirements

As we were hinted to in our last day at the office, we are planning to push out a rather big update to our current banking system that will make us more competitive in the banking scene. Here’s a list of requirements that we’ll have to implement before we can push our new update live.

  1. Give users the option to open up a checking account to go along with their savings account.
  2. Limit the withdrawal amount from the checking account to $250/day.
  3. Limit the number of withdrawals from the savings account to 3/month.
  4. Give the users a two percent interest increase on their savings account per month.
  5. Give users the ability to make transfers between accounts.

Getting Started

To start, let’s go ahead and create our checking account class keeping in mind the withdrawal limit specified above.

Pretty straight forward, nothing we haven’t seen here if you’ve been following the series. Take a look at the withdraw method, see how we handled point two on our requirements list?

Let’s move on to our BankMember class and compose it with a new checking account.

Perfect! We’re moving along at a very efficient rate here. The big update isn’t seeming so big anymore huh? Believe it or not, we’ve already completed the first two points of our new requirements list, so let’s not stop here, let’s implement points three and four with a quick update to our savings account file.

Great! Things have been going very well today and we haven’t even had our 15 minute morning stand up! But I can’t help but to notice that our code isn’t very DRY compliant, and it loosing a bit of its modularity.

Take another close look at our checking and savings account files. They are both very similar. For starters, they are both a different type of bank account. But looking further, they both operate very much the same in some aspects and very different in others. And this my friend, is a very bright red flag hinting towards a proper use of inheritance.

Finding the Commonalities

The first step to implementing inheritance is taking your two similar objects and picking out whats shared among them both. Lets create a list of shared data between our checking and savings account classes.

  • _memberId: number
  • _balance: number
  • deposit(amount: number): void
  • withdraw(amount: number): void

Because these four methods and properties are the same across both classes, it is why earlier I called out that we weren't being very DRY compliant. But how do we fix this you ask; We’ll fix it through inheritance! We’ll take the four general account properties and methods and throw them into a base class that our specific checking and savings accounts can then extend while providing their own more concrete implementations.

“…inheritance is, ‘the process of structuring a class hierarchy of similar objects that can extend the general functionality of it’s parent while making it’s own implementation more concrete.’”

Creating the Base Account Class

Lets go ahead and create this base class that we were just talking about.

We have a few things to note here. For starters, do you see that all the four common pieces of information now reside in this new base Account class? Also we changed our _memberId and _balance from private to protected so that our extending classes can utilize their values. Now finally, you’ll see the word abstract a couple of times here, one before the class keyword at the top of the file, and one right before the withdraw() method definition. Were not going to go over the ins and outs of the abstract keyword here, but for now just know that since the class is declared as abstract, we cant new up a version of the base Account class. And we can’t define an implementation for the abstract withdraw() method, it’l be left up to the sub classes to provide their own implementation.

Extending the Base Account Class

With the base class in play, we can now go ahead and extend it in our two specific accounts classes.

Ahhhh! Sweet, sweet inheritance. Not only did it extract out all the repeated code into one place that controls all, but it also decreased both of the file sizes by close to 40 lines each! Imagine the effectiveness of this in a large production application. But most important over all is now our specific account classes hold all of the concrete implementation that our application needs to function while inheriting everything else from its base class, such as the things that stays the same across all sub classes, like in this case, making deposits!

Lets go ahead and give our application a test run before we send it in to QA.

Application Test Run

Everything works as expected! Perfect 👍!

Signing Off

Inheritance is the process of structuring a class hierarchy of similar objects that can extend the general functionality of it’s parent while making it’s own implementation more concrete. Inheritance is very beneficial in keeping our code DRY compliant and happy side effect of this is that it helps to keep our file sizes small. It can at times be tricky, but remember if you ever find yourself stuck over whether a scenario requires inheritance, extract whats common amongst a group of similar objects and that will be a great place to start.

Somethings Missing..

Hmmmm.. I bet you’ve caught a key mistake within our mornings work. We never actually implemented number five of our requirements list, giving users the ability to transfer funds between different accounts. And you are absolutely right 😄. I’ve decided to save that piece of functionality for the last part of our series in Object Oriented Principles in Typescript where we’ll be taking a dive into polymorphism!

Hope you guys enjoyed today’s article on inheritance! And hope you guys can begin to use inheritance in your code bases starting today! Remember to keep an eye out for what is sadly going to be the last part of this series where we’ll be wrapping everything up as we add the final touches to our new banking application. Stay tuned!

Extras!

Inheritance can be hard! Here is a link to another article where inheritance seems to be the answer to the naked eye, but in terms of writing clean functional software, it didn’t quite hold up to standards. Give it a read to solidify your understanding even further.

Link to Files on Github

--

--

Raymond Johnson

Freelance software engineer with a passion for tech and progressing the knowledge of others, as well as myself with the things that will make us better devs.