Python OOPs - Inheritance in Python

Table of Contents

Inheritance

Python provides support for inheritance like others programming language
Inheritance is a concept by which a class can extend the facilities of another class or multiple other classes.
Syntax:

class BaseClassName:
    Base class statements
class DerivedClassName(BaseClassName):
    Derived class statements

DerivedClassName is a derived class (or sub class) inherited from BaseClassName which is known as base class (or super class)
The name BaseClassName must be defined in a scope containing the derived class.

Inherited attributes

The derived class will have all the attributes of its base class
Example:

class Person:
    def printme(self):
        print("I am in Person:printme()")

class Employee(Person): # Inherits/Extends the Person class
   pass

p = Employee()  # Create instance of derived class or sub class
p.printme()     # prints "I am in Person:printme"

Employee class inherits Person in class Employee(Person).
TheEmployee will inherits all of its attributes , currently method printme
Therefore, with "p" which is an instance of derived class can also invoke printme

Overriding in python

A derived class overrides the base class method
If a method/attribute is defined in the derived class and in the base class, the member in the derived class will override the one in the base class.
Example:

class Person:
    def printme(self):
        print("I am in Person:printme()")

class Employee(Person):
    def printme(self):
        print("I am in Employee:printme()")

p = Employee()  # Create instance of derived class or sub class
p.printme()     # prints "I am in Employee:printme"

Method printme is defined both in derived class and base class.
When we call printme using the derived class instance, it will completes replace (override) the method of base class
Therefore it will print "I am in Employee:printme"

Improve base class attributes or methods

We call base class method from derived class
A derived class can extend or improve the base class method by calling it in side another method
We can call/invoke a base class method in many ways
Example 1

# One way of calling base class method and imprive its features
class Person:
    def printme(self):
        print("I am in Person:printme()")

class Employee(Person):
    def printme(self):
        print("I am in Employee:printme()")
        Person.printme(self)
        print("Ending Employee:printme()")

e = Person()    # Create instance of base class
e.printme()     # Call base class printme()
print("-" * 30) # Separator
p = Employee()  # Create instance of derived class or sub class
p.printme()     # Call derived class printme()

I am in Person:printme() ------------------------------ I am in Employee:printme() I am in Person:printme() Ending Employee:printme()
e.printme() class the base class printme and print me one line i.e."I am in Person:printme()"
In derived class printme(), Person.printme(self) calls base class printme(). Here we have added 2 more lines to print before and after the call.
So we have improved the base class printme method somehow from 1 line to 2 line.
Like wise we improve the base class method features in python

Python super() built-in function

We can call a base class method using super() built-in function
Let us change the previous example to use super

class Person:
    def printme(self):
        print("I am in Person:printme()")

class Employee(Person):
    def printme(self):
        print("I am in Employee:printme()")
        super(Person, self)     # Using super() calling base class printme()
        print("Ending Employee:printme()")

e = Person()    # Create instance of base class
e.printme()     # Call base class printme()
print("-" * 30) # Separator
p = Employee()  # Create instance of derived class or sub class
p.printme()     # Call derived class printme()

I am in Person:printme() ------------------------------ I am in Employee:printme() I am in Person:printme() Ending Employee:printme()
Here super(Person, self) calls the printme() method in base class Person

Multiple inheritance in Python

A python class can be derived from multiple base classes
The derived class will have all the features of the base classes that it inherits
Example:

class BaseClass1:
    pass
class BaseClass2:
    pass
class DerivedClass(BaseClass1, BaseClass2):
    pass

Here DerivedClass class is derived from both BaseClass1 and BaseClass2
The base classes of a derived class can be found using a special attribute of a class namely __bases__
If we want to see the base classes of DerivedClass :
Example:

print(DerivedClass.__bases__)

(<class 'main.BaseClass1'>, <class 'main.BaseClass2'>)
__bases__ provides a tuple containing base classes of a derived class

Multilevel inheritance in Python

Multilevel inheritance refers to a mechanism in Object Oriented programing where once derived class is derived from base class and the same derived class is again derived into a new class
Example:

class BaseClass1:
    pass
class BaseClass2(BaseClass1):
    pass
class DerivedClass(BaseClass2):
    pass
print(DerivedClass.__bases__) # (<class '__main__.BaseClass2'>,), DerivedClass's base class is BaseClass2
print(BaseClass2.__bases__)   # (<class '__main__.BaseClass2'>,), BaseClass2's base class is BaseClass1

(<class 'main.BaseClass2'>,)
(<class 'main.BaseClass1'>,)

Here DerivedClass class is derived from BaseClass1 and BaseClass1 is derived fromBaseClass2

MRO - Method Resolution Order in Python

The attributes when we trying to fetch, is first searched in the current Class.
If python does not find the attribute, it tries to search in all its base classes in depth first and left to right order until it finds it first occurrence.
This order is known as Method Resolution Order in Python
Example:

class BaseClass2:
    y = 20
class BaseClass1:
    x = 10
class DerivedClass(BaseClass1, BaseClass2):
    z = 30
d = DerivedClass()  # Create a derived class object
print(d.z)  # prints 30
print(d.y)  # prints 20
print(d.x)  # prints 10

Here DerivedClass is derived from BaseClass1 and BaseClass2
print(d.z) - When we try to fetch "z" - as per MRO python checks it in DerivedClass first and it finds "Z" in DerivedClass, so it stops searching and prints it.
print(d.y) - "y" is not found in DerivedClass , the python searches "y" in all its base classes. As per MRO left base class is BaseClass1, so python searches "y" in it and stops and prints as "y" is found
print(d.z) - For "z" python again goes as per MRO - first DerivedClass, then BaseClass1 - not found , then tries BaseClass2 and it is found it stops search and prints value of "z"
If python does not find the attribute in any of its base classes it raises AttributeError

Click any Link
to navigate to certain page easily
Write a line to us
Your Email
Title
Description