I was studying Object Oriented Programming concepts last week and I decided to share a sum up about one of them: inheritance.
Inheritance
Inheritance allows classes to share their attributes, methods and functionalities to other classes. So in order to link those classes inheritance adopts a hierarchical schema relationship.
In inheritance hierarchy we have the parent class which is the class that gives its features to another class. They can also be called base class or super class.
On the other hand we have the child class which is the class that inherits the features from another class. They can also be called sub class or derived class.
And why is that relevant?
Inheritance then makes it possible to create an increasingly specialized hierarchical structure of classes. The big advantage of this is not having to start from scratch to specialize an existing class. The child class should be a specific implementation of unique attributes/methods/functionalities from a more generic class that shares similarities. So let’s go to a Python example.
Let’s say we create a class called Person which has the first_name and last_name as attributes. That would cover a generic situation if we assume all people are likely to have a first name and a last name, right? Proceeding from that we also create a class called Employee. We can say all employees are also persons so we will make our Employee class inherits the Person class attributes and methods, so the Person class will become Employee’s parent class. If we go a little further we also could create a class called, for example, Developer. And for our example we will assume that all developers are also employees so that they will inherit attributes and methods from its parent class (which in this case is the Employee class). So we could write something like this:
Note that the Developer class inherits features from the Employee class which is child of the Person class. So the Developer class also inherits the attributes and methods related to the Person class. This is a multilevel inheritance situation.
super()
Also note that in addition to pass the parent class as an argument when creating the child class we also use the super keyword as a reference to make our child classes to inherit the parent’s functionalities. So basically what we’re doing is using super in our constructor/init method and passing the attributes related to the parent class as arguments so they can be used in the parent’s class constructor.
Method Overriding
It’s basically to redefine a class method that is already defined in its parent class. So let’s go back to our previous example. Let’s say you want to change the greeting for the Developer class but instead of creating a different method as we did (dev_greeting method) we want to override the existing greeting method. Now when calling the greeting method for an instance of the Developer class we would be calling the overridden greeting method and would print out our overridden greeting:
We could also add something else to the existing greeting method, printing out the greeting from the parent class plus our specific greeting for the Developer class. Like this:
Multiple Inheritance in Python
In Python you will find multiple inheritance which means a child class can have more than one parent class and it will inherit all the methods and attributes of all its parent classes. See the example below:
It’s also relevant to mention that when using the super keyword and referencing any methods from the parent classes in the child class you will notice a behaviour called Method Resolution Order (MRO). For example, let’s say you use the super keyword to reference a method from one of the parent classes in the child class and create an instance of this last one. The instance methods, including the init method, will be executed based on the order defined by the classes inheritance as shown in the example below:
So in this case when creating a Child class instance, its init method is read and references the parent classes init methods too. But since the Parent1 class has no init method, the MRO allows to go to the next parent class init method to be resolved, which in order is the Parent2 class.
This behaviour can be really confusing depending on the complexity your code reaches. In other programming languages such as Java you're not allowed to use multiple inheritance in order to avoid possible runtime errors (like duck typing examples in Python). Things like inheriting from multiple classes that declare a method with the same name but with different signatures can be really confusing and complex to deal with if you don't track them properly. Which can also demand a lot of work and raise confusing runtime errors that are hard to deal with.
Top comments (1)
Talking about your own classes, inheritance may or may not be useful. It is often used to prevent redundancy. Sometimes you will create abstract parent classes simply to have a place for the code. If you place it there, all children will inherit the same code, which may be easier to maintain.
It is a completely different thing with inheritance in larger systems, like for example the windows GDI. This is a fairly large hierarchy that may give you access to thousands of underlying methods and properties. You just need to inherit EVERYTHING from one of the main classes, as this is the only way to be part of the family. Does this make any trouble? Not really. Even if you inherit the whole rainforest, that sits below the surface, you often will not even recognize this.