Help support the author by donating or purchasing a PDF copy of the book from EJunkie!

Buy me a coffeeBuy me a coffee

Chapter 20 - OOP Inheritance

20.1 - What is inheritance?

In programming we often come across objects that are quite similar or we may see that one class is a type of another class. For example, a car is a type of vehicle. Similarly, a motorbike is a type of vehicle. We can see a relationship emerging here. The type of relationship is an “is a” relationship.

In object oriented programming we call this inheritance and inheritance helps us model an is a relationship. Inheritance is one of the pillars of object oriented programming and we’ll be exploring it in this chapter.

There is some important terminology around inheritance that we must clarify before we look any deeper into it. Let’s go back to our example of cars and motorbikes being types of vehicles. If we look at each of these as a class, we would call the vehicle class a base class or parent class and the car and motorbike classes, derived classes, child classes or sub classes (they may be referred to differently depending on what you’re reading, just know they are exactly the same thing).

We can look at inheritance in programming the same way we do in real-life where a child inherits characteristics from its parents, in addition to its own unique characteristics. In programming, a child class can inherit attributes and methods from its parent class.

20.2 - Parent & child classes

We can create a parent which will act as a base from which subclasses can be derived. This allows us to create child classes through inheritance without having to rewrite the same code over and over again.

Let’s say we have Rectangle and Square classes. Many of the methods and attributes between a Rectangle and Square will be similar. For example both a rectangle and a square have an area() and a perimeter(). Up until now we may have implemented these classes as follows:

And we would have used them as follows:

This seems a little bit redundant however as both a square and rectangle have 4 sides each and they both have an area and a perimeter. If we look more closely at this situation we notice that a square is a special case of a rectangle in which all sides are the same length.

We can use inheritance to reflect this relationship and reduce the amount of code we have to write. In this case a Square is a type of Rectangle so it makes sense for a square to inherit from the rectangle class.

Let’s look at this code again but this time I have made changes to the square class to reflect this relationship. There are a few new things going on here but I’ll explain after.

The first change here is when we define the name of the Square class. I have class Square(Rectangle). This means that the Square inherits from the Rectangle class.

The next change is to the square’s __init__() method. We can see we are calling a new super() method. The super() method in Python returns a proxy object that delegates method calls to a parent or sibling of type. That definition may seem a little confusing but what that means in this case is that we have used super() to call the __init__() method of the Rectangle class, which allows us to use it without having to re-implement it in the Square class. Now, a squares length is length and its width is also length as we passed length in twice to the call to the super()’s __init__() method.

Since we’ve inherited Rectangle in the Square class, we also have access to the area() and perimeter methods without having to redefine them. We can now use these classes as follows:

As you can see, the super() method allows you to call methods of the superclass in your subclass. The main use case of this is to extend functionality of the inherited method.

With inheritance we can also override methods in our child classes. Let’s add a new class called a Cube. The cube will inherit from Square (which inherits from Rectangle). The Cube class will extend the functionality of the area method to calculate the surface area of a cube. It will also have a new method called volume to calculate the cubes volume. We can make good use of super() here to help us reduce the amount of code we’ll need.

Let’s look at how we do this:

We can now use this class as shown:

As you can see, we haven’t had to override the __init__() method as it’s inherited from Square. We have however overrided the area() method from the parent class (Square) on the Cube to reflect how the area of a cube is calculated. We have also used the super() method to help us with this.

We have also extended the functionality of cube to include a volume() method. Again, we have used the super() method to help with this.

As you can see, by using inheritance we have greatly reduced the amount of code compared to how we would have implemented these three classes previously.

I just want to go back to overriding the __init__() method for a second. Let’s assume a Person class and an Employee class that is derived from Person. Everything about an employee is the same as a Person but the employee will also have an employee ID.

Let’s look at how we would implement these:

We can now use these as follows:

The reason I’m showing you this is because, although I’ve already shown how to override methods, people get confused when overriding the __init__() method to also include new attributes on the derived class.

20.3 - Multiple inheritance

So far we’ve looked a single inheritance. That is, child classes that inherit from a single parent class. Multiple inheritance is when a class can inherit from more than one parent class.

Th;is allows programs to reduce redundancy, but it can also introduce a certain amount of complexity as well as ambiguity. If you plan on doing multiple inheritance in your programs, it should be done with care. Give thought to your overall program and how this might affect it. It may also affect the readability of your programs. For example:

Which method is the C class referring to? The method from A or the method from B? This may make your code harder to read. In Python, when calling method() on C, Python first checks if C has an implementation of method then it checks if A has implemented method. It has in this case so use that. If it hadn’t then Python would check each parent class in turn (A, B, ……) and so on until it finds the first parent class to have implemented method.

I’m not going to go too deep into multiple inheritance as it’s quite self explanatory on how to use it, so I’m only going to give one example of how it can be used:

This can be used as follows:

20.4 - Exercises

Question 1

Create two classes: Person and Employee. The person class should have name and age attributes. The employee class should have one additional employeeId attribute. The employ should also have clock_in and clock_out methods. When implemented correctly, you should be able to use the two classes as follows:

Note: You are to use inheritance to implement the employee class.

Question 2

Create a Shape class. The shape class should have two attributes: num_sides and side_length. It should also have one method called show_type()

Create two other classes: Triangle and Pentagon. Each of these classes should inherit from the Shape class.

Both the Triangle and Pentagon classes should have area() methods.

When implemented correctly, you should be able to use your classes as follows:

Note: The triangle is an equilateral triangle and the pentagon is a regular pentagon. You can find the formulae for both of their areas online.

Question 3

Create a Clock class. It should have three attributes: hour, minute, and second. It should also have a method called show_time() that displays the time in 24 hour time. It should also have a method called tick() that advances the time by 1 second.

Create a Calendar class. It should have three attributes: day, month, and year. It should have two methods, one called show_date() and the other called next() that advances the date to the next day.

Create a third class called CalendarClock that inherits from both Clock and Calendar. It should have one method called tick() that advances the time by 1 second, and a second method, show_date_time() that shows the date and time.

When implemented correctly, you should be able to use your classes as follows:

Note: There are a few ways of completing this question, however I want you to use multiple inheritance. If you do, then the code for CalendarClock should be quite short.

Help support the author by donating or purchasing a PDF copy of the book from EJunkie!

Buy me a coffeeBuy me a coffee

Previous Chapter - Next Chapter