Inheritance in Python
Inheritance is a fundamental facet of object-oriented programming languages, including Python. This article will explore the concept of inheritance in Python in detail.
Contents
Best-suited Python for data science courses for you
Learn Python for data science with these high-rated online courses
What is Inheritance in Python?
Inheritance in Python is referred to as the ability where the child class (derived class) inherits or acquires all the properties and behaviors from the parent class (base class).
In object-oriented programming, inheritance is largely used to improve code reuse, by that I mean the new class can automatically use all the attributes and methods of the old class without having to copy the code again. As a result, you can declare what is unique to your new class, which will override the old class’s behaviour. The old class is called superclass, parent, or base class and the class that inherits from a parent (or super) class is called a subclass, child, or derived class.
Let’s decipher this with the help of an example. You might have heard of the popular Spanish thriller series La Casa de Papel (aka Money Heist). Well, the series showcases a professor and his group of robbers as they indulge in nerve-wracking heists and take hostages along the way with their signature red jumpsuits and Dalí masks. It’s hard to imagine a thriller without its main characters. These main characters can be categorized like you have a professor, a gang of robbers, then there are law enforcement officers, politicians, etc. Now, creating a separate class for each of these individuals is pointless.
Instead, you can have a superclass called MoneyHeist_Charecters and use this as a parent class for the Robber class, Law Enforcement Officers class. The parent class can have common properties and behaviors shared by all the child classes. In addition, each child class can have its own properties and classes.
When to Use Inheritance?
Although the definition of inheritance is very simple, it can become a complicated, tangled mess when used unwisely. The most common and beneficial use of inheritance is when you want to perform differential programming. That is when you want to reuse the entire interface and implementation from the superclass, but with a few tweaks and enhancements.
Well, I guess that’s enough theory! Let’s try to grasp the concept by actually implementing it. Let’s suppose that we’re creating an inventory application for a pet sanctuary. Here, we can name different kinds of objects such as parrots, cats, dogs, hamsters, rabbits, etc. Now, does it make to write code for each cat, each dog, and so on?
Programming Online Courses and Certification | Python Online Courses and Certifications |
Data Science Online Courses and Certifications | Machine Learning Online Courses and Certifications |
Types of Inheritance in Python
In Python, we have different types of inheritance that we can implement in different situations. Let’s discuss each of these in detail with help of examples.
Single Inheritance in Python
Single inheritance is the simplest of inheritance models. In this type, a child class inherits from a single parent class as shown below.
#A program to demonstrate single inheritance # Base or parent class # Same as Pet(object) class Pet: #constructor def __init__ ( self , pet_type , name , bdate ): self. pet_type = pet_type self. name = name self. bdate = bdate #method to print details def details ( self ): print ( "I am pet" ) # Derived or child class - inherits base class Pet class Cat (Pet ): #constructor def __init__ ( self , pet_type , name , bdate ): self. name = "Grey " + name self. pet_type = pet_type def sounds ( self , sound ): return sound pet1 = Pet ( 'cat' , 'Tiffany' , '2019-07-08' ) pet2 = Cat ( 'cat' , 'Gatsby' , '2018-07-08' ) pet1. details ( ) #calls parent class version of details() pet2. details ( ) #calls parent class version of details() print (pet2. name , "is a" ,pet2. pet_type , "and it always runs around with" ,pet2. sounds ( "attention-seeking meows" ) )
To summarize this example:
- There is a subclass called Cat that inherits the attributes and methods of the base class Pet.
- In addition, the class Cat also has its own method, sounds
- We have used special Python object initialization method __init__()
Okay, I see that there are a few new terms like __init__, self, method overriding, etc. Let’s explore them in detail.
__init__ method
The line pet1 = Pet(‘cat’, ‘Tiffany’, ‘2019-07-08’) from the previous example creates a new instance of Pet class, then initializes its data by calling the class’s __init__ method. The __init__ function runs automatically when the class is called. Every class that you create can provide an __init__ method that specifies how to initialize an object’s attributes.
#constructor def __init__ ( self , pet_type , name , bdate ): self. pet_type = pet_type self. name = name self. bdate = bdate
You can actually write your own version of __init__() method, i.e. override it.
‘self’ in Python
Most often the very first argument of a class method is self. The argument self just points to the instance of our class that we’re currently working with. From Python’s perspective it’s just a convention, I mean the name self has absolutely no special meaning. It simply binds the arguments passed with the object’s attributes.
Method Overriding
So far, we have looked at the class Cat which inherited all the attributes and behaviors of parent class Pet. In addition, the class Cat also created its own unique method, that is specific to the derived class. However, the child class can create its own version of the inherited attributes and methods by a technique called overriding. We call this method overriding.
Let’s try to understand that with the help of an example.
#A python program demonstrating method overriding # Base or parent class # Same as Pet(object) class Pet: #constructor def __init__ ( self , pet_type , name , bdate ): self. pet_type = pet_type self. name = name self. bdate = bdate #method to print details def details ( self ): print ( "I am pet" ) class Dog (Pet ): def __init__ ( self , pet_type , name , bdate , breed ): super ( ). __init__ (pet_type , name , bdate ) self. breed = breed def sounds ( self , sound ): return sound def details ( self ): print ( 'I am' , self. name , ',a' , self. breed ) pet1 = Pet ( 'Dog' , 'Tiffiny' , '2019-07-08' ) pet2 = Dog ( 'Dog' , 'Toby' , '2018-07-08' , 'bull dog' ) pet3 = Dog ( 'Dog' , 'Max' , '2018-07-08' , 'Tibetan Mastiff' ) pet1. details ( ) #invokes the parent version of details() pet2. details ( ) #invokes class Dog version of details() print (pet3. name , "is a" ,pet3. breed , ", plays well with other dogs, & never" ,pet3. sounds ( "growls" ) , "at kids" )
The Dog class overrides a parent method Details and creates its own version. The line pet2 = Dog(‘Dog’, ‘Toby’, ‘2018-07-08’, ‘bull dog’), invokes the class Dog version of details().
The super() method
You can override any method of the parent class, including __init__(). In the above example, notice that __init__ method is defined in both classes. When this happens, the method in the child class overrides the method in the parent class. Basically, by overriding, we are trying to extend the definition of the class rather than simply replacing it.
In simple terms, you can still use the parent class version of the method and append to it the additional details from the child class. This can be achieved using built-in-function super(). By using the function super(), we are basically bringing a parent method into the child method to make use of it. The super() in the below example gets the definition of Pet, the parent class.
#Python code snippet demonstrating super() method class Dog (Pet ): def __init__ ( self , pet_type , name , bdate , breed ): super ( ). __init__ (pet_type , name , bdate ) self. breed = breed
Now that you are clear on these important topics related to inheritance, let’s go back to discussing different types of inheritance.
Multiple Inheritance in Python
In multiple inheritances, the derived (child class) class inherits from more than one base (parent class) class. Here’s another interesting multiple inheritances in Python example.
#Python program demonstrating multiple inheritance #Base Class 1 class Pets: def domesticated ( self ): return "Legalized Pet" #Base Class 2 class WildAnimals: def tamed ( self ): return "Is a wild animal" #Derived Class (Child class) class exotic_pets (WildAnimals , Pets ): pass Tiger = exotic_pets ( ) print (Tiger. tamed ( ) , "and" , Tiger. domesticated ( ) )
Multilevel Inheritance in Python
In a multilevel inheritance model a derived class inherits another derived class.
#Python program demonstrating multilevel inheritance #Base Class class Pet: #constructor def __init__ ( self , name ): self. name = name #method to print name def getName ( self ): return self. name #Derived Class class Mammal (Pet ): def warm_blooded ( self ): return True #Derived Class class Cat (Mammal ): #constructor def __init__ ( self , name , pet_type , breed ): Mammal. __init__ ( self , name ) self. pet_type = pet_type self. breed = breed def getDetails ( self ): return "is a " + self. breed + " " + self. pet_type def sounds ( self , sound ): return sound pet3 = Cat ( 'Max' , 'Cat' , 'Siberian' ) print (pet3. getName ( ) , pet3. getDetails ( ) ) print ( "Is" , pet3. getName ( ) , "warm blooded?" , pet3. warm_blooded ( ) )
Hierarchical Inheritance in Python
In Python, if more than one derived class is created from a single base class, we call that hierarchical inheritance. Here’s a simple example:
#Python Program demonstrating hierarchical inheritance #Base Class class Pet: def __init__ ( self , pet_type , name , bdate ): self. pet_type = pet_type self. name = name self. bdate = bdate def details ( self ): print ( "I am pet" ) #Derived Class 1 class Cat (Pet ): def __init__ ( self , pet_type , name , bdate ): self. name = "Grey " + name self. pet_type = pet_type def details ( self ): print ( 'I am cute pet' , self. pet_type , 'people call me' , self. name ) #Derived Class 2 class Dog (Pet ): def __init__ ( self , pet_type , name , bdate , breed ): super ( ). __init__ (pet_type , name , bdate ) self. breed = breed def sounds ( self , sound ): return sound def details ( self ): print ( 'I am' , self. name , ',a' , self. breed ) pet1 = Pet ( 'cat' , 'Tiffiny' , '2019-07-08' ) pet2 = Cat ( 'cat' , 'Gatsby' , '2018-07-08' ) pet3 = Dog ( 'dog' , 'Toby' , '2018-07-08' , 'bull dog' ) pet4 = Dog ( 'dog' , 'Max' , '2018-07-08' , 'Tibetan Mastiff' ) print (pet1. name ) print (pet2. name , "is a chubby" , pet2. pet_type ) pet2. details ( ) print (pet3. name , "is a" ,pet3. breed , "and it always" ,pet3. sounds ( "growls" ) ) pet4. details ( )
The concept details that we can learn from this example are:
- There are have 2 subclasses Cat and Dog that inherit the attributes and methods of the base class Pet. In addition they also have their own attributes and methods
- A child class is simply a specialization of parent class
- Both Cat and Dog override a parent method Details and create their own version. You can override any method, including __init__(). This is called method overriding
- The class Dog has a method called sounds, which is not present in its parent class Pet
- Now you know how to add or override a parent class method. You have two versions of same method. How to call the parent version of that method? In such scenario fucntion super() comes to your aid
- The super() brings in the definition of parent class Pet into child class
- The __init__() method automatically takes care of passing the argument self to parent class. All you need is to give optional arguments if there are any
- In the class Dog, the line self.breed = breed and the instance method sounds is the new code that makes class Dog different from a Pet
Hybrid Inheritance in Python
When inheritance consists of multiple combinations of different inheritance models that we discussed till now, we call that hybrid inheritance.
#Python program demonstrating Hybrid inheritance #Base Class 1 class Pets: def pets_info ( self ): print ( "Legalized Pet" ) class Cat (Pets ): def cat_info ( self ): print ( "I am cat" ) class Dog (Pets ): def dog_info ( self ): print ( "I am a fiercely loyal dog" ) # Wild_Cat inherits properties of Pets and Cat class Wild_Cat (Cat , Pets ): def wildcat_info ( self ): print ( "A mighty wild cat" ) # create object w_cat = Wild_Cat ( ) w_cat. pets_info ( ) w_cat. cat_info ( ) w_cat. wildcat_info ( )
Other Special In-built Functions to Check Inheritances
issubclass( )
This function is used to check if a class is derived from a particular base class. If the classes share a parent-child relationship, it returns a Boolean value of True, else it returns False.
You can also explore- How to Find the Factorial of a Number Using Python
isinstance( )
This function is used to check if an object is an instance of a particular class or any of the classes it has been derived from. This function takes two arguments – the object, and the class we are checking it against. If the object is an instance, it returns a Boolean value of True, else it returns False.
You can also explore- Variables in Python
Consider the below example to understand both the predefined functions:
class parent: def display(self): print("Parent Class Method") class child(parent): def display(self): super().display() print("Child Class Method") #Check if child is derived from parent print(issubclass(child,parent)) #Check if parent is derived from child print(issubclass(parent,child)) X = child() Y = parent() #Check if object X is instance of child print(isinstance(X,child)) #Check if object X is instance of parent print(isinstance(X,parent)) #Check if object Y is instance of child print(isinstance(Y,child)) #Check if object Y is instance of parent print(isinstance(Y,parent))
Output:
Conclusion
That’s it guys! Hope you found this interesting. To summarize, inheritance supports code reusability, by allowing you to create a generic parent class and a more unique child class, which automatically gets access to functionalities of the parent class once it inherits the parent class.
Top Trending Article
Top Online Python Compiler | How to Check if a Python String is Palindrome | Feature Selection Technique | Conditional Statement in Python | How to Find Armstrong Number in Python | Data Types in Python | How to Find Second Occurrence of Sub-String in Python String | For Loop in Python |Prime Number | Inheritance in Python | Validating Password using Python Regex | Python List |Market Basket Analysis in Python | Python Dictionary | Python While Loop | Python Split Function | Rock Paper Scissor Game in Python | Python String | How to Generate Random Number in Python | Python Program to Check Leap Year | Slicing in Python
Interview Questions
Data Science Interview Questions | Machine Learning Interview Questions | Statistics Interview Question | Coding Interview Questions | SQL Interview Questions | SQL Query Interview Questions | Data Engineering Interview Questions | Data Structure Interview Questions | Database Interview Questions | Data Modeling Interview Questions | Deep Learning Interview Questions |
This is a collection of insightful articles from domain experts in the fields of Cloud Computing, DevOps, AWS, Data Science, Machine Learning, AI, and Natural Language Processing. The range of topics caters to upski... Read Full Bio