10) d. Inheritance

What is great about object oriented programming (OOP) is that if you want to create a custom class based on some existing class you can use inheritance to do so. Instead of creating a new class from scratch you can extend a given class (called base class) to keep all of its attributes and methods and then add your own or override some existing ones with what you want.

Here is a simple example to illustrate inheritance.

1
2
3
4
I'm alive.
I go to school.
I'
m alive.
I go to office.

In the above example, you see how we wanted to create two different classes. But instead of rewriting all the code again, we “reused” the existing code from class. This makes your code neater and more structured.

Why do we need inheritance? Can’t we just copy-paste that class into our class?

In the previous example, the human class is called as the base class. All new classes created from it are called child classes or sub classes.

In a way it’s somewhat similar to functions where you label a piece of code that you can call whenever you want. Over here, you’ve labeled a definition and are adding that chunk of attributes / methods into your new class directly. For the sake of understanding and simplicity, when you inherit a class it’s like you have copy-pasted the base class’s definition inside your new class.

This becomes increasingly useful when you have to inherit from multiple classes (which we will come to in the next chapter)! Imagine copy-pasting all that code from many classes and putting them into your class. This would become even more nightmarish when each of the base classes are being owned and modified by other people (perhaps some other company or different teams). If you simply copy-pasted the base-class content inside your own class, imagine how complicated it would be to find out what class got changed, then copy-paste everything into your file repeatedly. With inheritance you just add one word (inside your class’s parenthesis) and you’re done!



Here is another example on inheritance. This example is lengthy. But stay with it. It brings out the beauty of inheritance in a way that over-simplified examples wouldn’t.

1
2
3
4
5
6
7
Output:
Gary 100 0
Tom 100 0

Gary attacks Tom
Gary 100 30
Tom 76.0 24.0




In this example with have added an additional method deal_damage to the Attacker class and overwritten the original take_damage method in the Defender class.

Please note that if you wish to overwrite the __init__ method in a subclass it is highly recommended to call __init__ method of the parent at some point to make sure all of instance state is setup properly.

1
2
Output:
Owen 100 85 0

What are the limitations of inheritance?

Let’s say that you inherited a parent class instead of copy-pasting it into your own (which might be illegal depending on the license of the company that provided you that class). What are the limitations of inheriting from a parent class?

Whenever you create child instances, you can call parent class’s methods. But you cannot refer to parent’s attributes directly. As an analogy to remember this, imagine that you are creating children. These children have access to their parent’s money. So inside the child class you can access all parent’s attributes. But you (outside the child class) cannot access their parent’s money.

Conclusion:

That said, as a general rule of practice it is considered wise to limit use of inheritance as much as possible. A simple reason for this is that when you have a big project that has tens or hundreds of classes and a good amount of inheritance between them then any changes made in a parent’s class may have a cascading unforeseen negative affects in all descending child classes. As such, the parent class and child classes are said to be “coupled” together. In other words, modifying the parent class may have unintended, accidental consequences on the child class. It also leads to code complexity.