Inheritance in Python
Overview
The object-oriented paradigm places a lot of emphasis on inheritance. Because we can use an existing class to create a new class rather than creating it from scratch, inheritance allows the program to reuse code.
With inheritance, the child class gains access to all the data members, functions, and properties defined in the parent class. A child class may also offer its particular implementation of the parent class's functions. A derived class in Python can inherit from its base class by simply putting its name in brackets after the derived class name.
Introduction
Python is one of the most eclectic programming languages. It supports multiple types of programming styles, from very basic functional coding to industry-level object-oriented programming. Due to its ease of syntax, python has become a popular choice of language for OOPs.
Inheritance is one of the pillar concepts of OOPs. In this article, we will take a look at this robust feature and its various types with examples. But before we dig deeper, we must get familiar with some essential coding concepts like Objects and Classes.
Classes and Objects
Inheritance is one of the pillars of the OOPs concept. Classes are used to implement inheritance. To dive deeper into its understanding, let’s take an example of newly approved society construction.
The first task is to create a blueprint of a house. In the programming world, this blueprint is not any different from the class definition. This blueprint will hold information on the functionalities and characteristics of each house in society.
Whenever any new house in the society is to be built, it will hold the property of the blueprint. Likewise, whenever an instance of a class is created, it contains all the methods and variables of the defined class.
Just like how space is utilized by the house in the construction site and not the blueprint, classes do not occupy any computational space, it’s instead the objects constructed using them that utilize this space.
Let’s see an example of how we code these classes, objects, and methods in a real-life coding example.
Example
Let’s consider the construction example again, but we need to make Python objects for these buildings. The following class is created as a blueprint for buildings where each building (object) following the “building” blueprint (class) will have default attributes like “height” and “architect”. We also construct a method to display these attributes upon calling them via the object.
Output:
What is Inheritance in Python?
Inheritance is the ability to ‘inherit’ features or attributes from already written classes into newer classes we make. These features and attributes are defined data structures and the functions we can perform with them, a.k.a. Methods. It promotes code reusability, which is considered one of the best industrial coding practices as it makes the codebase modular.
In Python inheritance, new class/es inherits from older class/es. The new class/es copies all the older class's functions and attributes without rewriting the syntax in the new class/es. These new classes are called derived classes, and old ones are called base classes.
For example, inheritance is often used in biology to symbolize the transfer of genetic traits from parents to their children. Similarly, we have parent classes (Base classes) and child classes (derived classes). In Inheritance, we derive classes from other already existing classes. The existing classes are the parent/base classes from which the attributes and methods are inherited in the child classes.
Syntax:
Here, DerivedClass is the class that will inherit from the BaseClass. The BaseClass is the class that will serve as the parent or superclass.
Example:
Output:
In the above example, we define a base class called Person with an __init__ method to initialize the name and age attributes, and a say_hello method to introduce the person. We also define a derived class called Student, which inherits from the Person class and adds a new attribute grade and a new implementation of the say_hello method to introduce the student.
We created an instance of the Person class and call its say_hello method, which outputs a message introducing the person. We also created an instance of the Student class and call its say_hello method, which outputs a message introducing the student and their grade.
Types of Inheritance in Python
Now that we are all set with the prerequisites to understand how inheritance in Python is carried out, let’s look at various inheritance types.
Single Inheritance in Python
Single Inheritance is the simplest form of inheritance where a single child class is derived from a single parent class. Due to its candid nature, it is also known as Simple Inheritance.
Example
Output:
Multiple Inheritance in Python
In multiple inheritance, a single child class is inherited from two or more parent classes. It means the child class has access to all the parent classes' methods and attributes.
However, if two parents have the same “named” methods, the child class performs the method of the first parent in order of reference. To better understand which class’s methods shall be executed first, we can use the Method Resolution Order function (mro). It tells the order in which the child class is interpreted to visit the other classes.
Example:
Basic implementation of multiple inheritance
Output:
As we can see with the help of mro, the child class first visits itself, then the first parent class, referenced before the second parent class. Similarly, it visits the second parent class before the third parent class, and that’s why it performs the second parent’s function rather than the third parent’s. Finally, it visits any objects that may have been created.
Multilevel Inheritance in Python
In multilevel inheritance, we go beyond just a parent-child relation. We introduce grandchildren, great-grandchildren, grandparents, etc. We have seen only two levels of inheritance with a superior parent class/es and a derived class/es, but here we can have multiple levels where the parent class/es itself is derived from another class/es.
Example:
Output:
Hierarchical Inheritance in Python
Hierarchical Inheritance is the right opposite of multiple inheritance. It means that there are multiple derived child classes from a single-parent class.
Example:
Output:
Hybrid Inheritance in Python
Hybrid Inheritance is the mixture of two or more different types of inheritance. Here we can have many relationships between parent and child classes with multiple levels.
Example:
Output:
This example shows a combination of three types of python inheritance.
Parent1 -> Child1 : Single Inheritance
Parent1 -> Child1 -> Child2 : Multi – Level Inheritance
Parent1 -> Child2 <- Parent2 : Multiple Inheritance
The diagrammatic explanation of this hybrid inheritance is:
Special Functions in Python Inheritance
Python is a very versatile and user-friendly language. It provides some amazing in-built functions that make our lives easier when understanding inheritance, especially of a complex nature.
super() Function
Method overriding is an ability of any object-oriented programming language that allows a subclass or child class to provide a specific implementation of a method already provided by one of its super-classes or parent classes. This discrepancy is caused due to similar naming convention of the methods. Commonly we can see this situation when the parent’s init() is overridden by the child’s init(), and hence the child class cannot inherit attributes from the parent class.
Similarly, we can face this same problem with methods other than init but having the same naming convention across parent and child classes.
One solution is to call the parent method inside the child method.
Output:
Another way to solve this problem without explicitly typing out the parent name is to use super(). It automatically references the parent/base class from which the child class is derived. It is extremely helpful to call overridden methods in classes with many methods.
Example:
Output:
Alternately we can also call super() with the following syntax:
Here, the first parameter references the child class/subclass in the function.
issubclass()
The issubclass() function is a convenient way to check whether a class is the child of the parent class. In other words, it checks if the first class is derived from the second class. If the classes share a parent-child relationship, it returns a boolean value of True. Otherwise, False.
isinstance()
isinstance() is another inbuilt function of Python that allows us to check whether an object is an instance of a particular class or any of the classes it has been derived from. It takes two parameters, i.e. the object and the class we need to check it against. It returns a boolean value of True if the object is an instance and otherwise, False.
Example:
Output:
Advantages of Inheritance in Python
- Modular Codebase: Increases modularity, i.e. breaking down the codebase into modules, making it easier to understand. Here, each class we define becomes a separate module that can be inherited separately by one or many classes.
- Code Reusability: the child class copies all the attributes and methods of the parent class into its class and use. It saves time and coding effort by not rewriting them, thus following modularity paradigms.
- Less Development and Maintenance Costs: Changes need to be made in the base class, all derived classes will automatically follow.
Disadvantages of Inheritance in Python
- Decreases the Execution Speed: loading multiple classes because they are interdependent
- Tightly Coupled Classes: this means that even though parent classes can be executed independently, child classes cannot be executed without defining their parent classes.
Conclusion
We got a one stop tutorial on how to get started with inheritance in Python. We covered:
- Basics of classes and objects
- Types of inheritance with coding examples
- Common problems and how to solve it
- Special functions for Python inheritance
Inheritance is one of the core OOPs concepts that easily becomes one of the favorite trick questions by interviewers for SDE roles. Having a good grip on inheritance would not only give you a good chance at interviews but also improve your coding style and bring modularity.