Polymorphism in Python with Examples

Posted in /  

Polymorphism in Python with Examples
vinaykhatri

Vinay Khatri
Last updated on February 11, 2025

Object-Oriented Programming has four basic features, Inheritance, Data Abstraction, Data Encapsulation, and Polymorphism. And out of these features, Polymorphism is the crucial one, and if a Programming language does not support Polymorphism, it does not even consider an Object-Oriented Programming language.

As an object-oriented programming language, Python supports Polymorphism, and this tutorial will teach you what polymorphism is in Python and how to implement it. By the end of this tutorial, you will have a solid understanding of

  1. What is Polymorphism in Python
  2. Method Overriding
  3. What is function overloading and,
  4. Operator Overloading

What is Polymorphism in Python? OOPS Concept

Polymorphism is a Greek word that means “having Multiple Forms”, and in Programming, Polymorphism has the same concept but here it says an object can take many forms. In Python, the Polymorphism concept allows a particular object to perform different tasks in different scenarios.

The most common example of Polymorphism is the + operator. The + operator performs the addition operation between two number objects, and the same + operator performs string concatenation or joining between two string objects. This behaviour of the + operator, where it can take a different form in different scenarios, is a classical example of Polymorphism.

Note: Polymorphism does not apply to every Python object.

Another Real World Example of Polymorphism is you. You can be an Employee in a company, Husband or wife of your spouse and a striker while playing football. This acquiring of different forms at different places is what Polymorphism.

Let’s Build a solid understanding of Polymorphism with a common Python Example

Example: Python Polymorphism with len() function

In Python, you have used the len() function many times, as the name suggests, the len() function is generally used to calculate the total length of an object. But which length to compute depends upon the data type passed as an argument to the len() function.

For a list object, the len() function counts the total number of items present in the list. For a string, the len() function counts the total number of characters present in the string. For a dictionary object, the len() function counts the number of keys present in the dictionary.

The len() function name is the same for all the objects list, string, and dictionary, but it performs different operations on different objects. That is because Python supports Polymorphism.

Example

#list
employee = ['Rohan', 'Jay', 'Aman', 'Ravi', 'Shiv']

#string
message = 'welcome back to office'

#dictionary
jobs = {'Sales':3, 'IT':5, 'Management':2, 'Executive':1}

#count the list items
print("List count: ", len(employee))

#count the string characters
print('String Chracters count: ', len(message))

#count the dictionary keys
print('Dictionary Key Counts: ', len(jobs))

Output

List count:  5
String Chracters count:  22
Dictionary Key Counts:  4

How does Python Polymorphism work with Inheritance (Method Overriding)?

Mainly when it comes to class and objects we often use Polymorphism with Python inheritance . In Inheritance, the child or derived class can inherit the properties such as attributes, methods, and other data members from its parent or base class.

In method overriding, we first redefine a method in the child class with the same method name as the parent class. In method overriding, the inheriting of parent class methods in the child class is the concept of inheritance, and redefining the method with the same name is the concept of Polymorphism. This is how method overriding is a combination of two powerful object-oriented features.

Benefits of Method overriding

  1. Sometimes in inheritance, the parent class method does not satisfy the child class's functionality. We can extend the functionality by redefining the same method in the child class using method overriding.
  2. In multiple inheritances many child classes inherit from the single parent class, in that case, we can have method overriding in the child classes because there are solid chances that the parent class method does not fulfill all the requirements of all the child classes.

Example

Let’s write a Python program that demonstrates method overriding.

class Automobile():
    def __init__(self, name, price, speed, gear):
        self.name = name
        self.price = price
        self.speed = speed
        self.gears = gear

    def details(self):
        print("Vehicle Name:", self.name)
        print("Vehicle Price:", self.price)
        print("Vehicle max Speed:", self.speed)
        print("Vehicle total gears:", self.gears)

    def speed_detail(self):
        print("The Max Speed of the vehical is 120 Km/h")

    def gears_detail(self):
        print("This Vehicle has 5 gears")

#inherit the automobile class
class Car(Automobile):
    #speed method overriding
    def speed_detail(self):
        print(f"The Max Speed of this car is {self.speed} Km/h")
        
    #gears method overriding
    def gears_detail(self):
        print(f"This car has {self.gears} gears including reverse")

#inherit the automobile class
class Bike(Automobile):
    #speed method overriding
    def speed_detail(self):
        print(f"The Max Speed of this Bike is {self.speed} Km/h")

    #gears method overriding
    def gears_detail(self):
        print(f"This Bike has {self.gears} gears")

#Create the Car object
bmw = Car('BMW 3 Series', '44.86 Lakhs' ,'250', 'Automatic 8 Gear Box' )
bmw.details()  #call the parent details method 
bmw.speed_detail()     #call the overriden method
bmw.gears_detail()     #call the overriden method

print("\n\n")

#Create the Bike object
ktm = Bike('KTM 1190 RC8 R', '20 Lakhs', '280', '6' )
ktm.details()  #call the parent details method 
ktm.speed_detail()     #call the overriden method
ktm.gears_detail()     #call the overriden method

Output

Vehicle Name: BMW 3 Series
Vehicle Price: 44.86 Lakhs
Vehicle max Speed: 250
Vehicle total gears: Automatic 8 Gear Box
The Max Speed of this car is 250 Km/h
This car has Automatic 8 Gear Box gears including reverse

Vehicle Name: KTM 1190 RC8 R
Vehicle Price: 20 Lakhs
Vehicle max Speed: 280
Vehicle total gears: 6
The Max Speed of this Bike is 280 Km/h
This Bike has 6 gears

Built-in method overriding in Python

The code for built-in methods like abs(), len(), sum(), etc has already been written in the core Python <class object>. And by default, every class inherits the core Python object. We can see it by applying the mro() method to any class name. To override these inbuilt methods we can redefine their dunder methods for any custom class.

Example

class Orders:
    def __init__(self):
        self.cart = {'in process':[], 'canceled':[]}

    def buy(self, item):
        self.cart['in process'].append(item)

    #override the len() function for Orders() objects
    def __len__(self):
        return len(self.cart['in process'])

my_orders = Orders()
my_orders.buy('Shoes')
my_orders.buy('Jackets')

#len function on my_orders object
in_process= len(my_orders)

print("Total Items in process", in_process)

Output

Total Items in process 2

In the above example, we override the inbuilt len() function for the Orders() class and every time we call the len() function on any of the Orders() object it will invoke the overridden method.

How Python Polymorphism in Class Methods works

When we create an object of Python and call a method on that object, Python links that objects with the method during the runtime. Python checks look for the method using Method Resolution Order, which is a technique used by Python objects to call the correct method or other attributes defined in the class. Let’s say we have two different classes, and they both have methods with the same names. When we create the objects for both the classes and call those methods, Python will link the correct object with the correct method.

Example

class Car():
    def max_speed(self):
        print("The Max Speed of Car is 350 KM/H")

class Bike():
    def max_speed(self):
        print("The Max Speed of Bike is 300 KM/H")

#create an object of Car
car = Car()

#create an object of bike
bike = Bike()

#call the max_speed of class Car
car.max_speed()

#call the max_speed of class Bike
bike.max_speed()

Output

The Max Speed of Car is 350 KM/H
The Max Speed of Bike is 300 KM/H

Car and Bike both have the same method names max_speed() in the above example. But the Car’s object car invoked the max_speed() method of Car , and the Bike’s object bike called the max_speed() of the Bike class.

What is Function Overloading in Python?

Function overloading is also one example of Polymorphism. In Function overloading, we have different functions of the same names, with different parameters. But unfortunately, Python does not support Function Overloading, this is because Python is an interpreted programming language, it read and executes the code simultaneously.

If we try to define a new function with the same name and different parameters, it will override the existing function instead of overloading. The function overloading is supported by Static programming languages like C++, C, and Java.

Example of Function overloading

def area(shape, radius):
    result = 2 *3.14 *radius*radius
    print("The Area of the given {shape} is: ", result)

#this will override the above area function not overload
def area(shape, length, width):
    result = length * width
    print(f"The Area of the given {shape} is: ", result)

#this will throw an error if executed 
#area('circle',10)

area('rectangle, 10, 20)

Output

The Area of the given rectangle is:  200

Method overloading in Python is also not supported . The reason for not supporting method overloading is the same as function overloading.

What Operator Overloading in Python?

The operator overloading is an example of OOP’s Polymorphism, in which we can change the default behavior of an operator. The most common example of operator overloading is the Concatenation and Addition operator + . The + operator performs addition when both the values are integer or float, and it performs the string concatenation operation if both the values are of str data type.

Example

print(200+300) # 500  (addition)

print('200'+'300') #200300 (concatenation)

The above example demonstrates the inbuilt operator overloading of the + operator. But with Python operator overloading , we can change the default behavior of the operator for the class objects. To Overload the operators for class, we use the operator Magic Method, also known as the dunder method. Here is the list of all the operators and their dunder methods.

Operator Dunder Methods
+ __add__(self, other)
- __sub__(self, other)
* __mul __ (self, other)
/ __div__(self, other)
// __floordiv__(self,other)
% __mod__(self, other)
** __pow__(self, other)
+= __iadd__(self, other)
-= __isub__(self, other)
*= __imul__(self, other)
/+ __idiv__(self, other)
%= __imod__(self, other)
**= __ipow__(self, other)
< __lt__(self, other)
> __gt__(self, other)
<= __le__(self, other)
>= __ge__(self, other)
== __eq__(self, other)
!= __ne__(self, other)

Example 1: Overload the + operator for custom class object

Most operators require two operands to operate, so does the + operator. To overload the + operator for our custom class, we need to define the __add__() method in the Class. The __add__() method represent the + operator operation .

Example

class Products:

    def __init__(self, items):
        self.items = items

    #here self is the object on the left side of + operator
    # and other is the object on the right side of the + operator
    def __add__(self, other):
        return self.items + other.items

home = Products(200)
office = Products(400)

print("The total Products are:", home + office)

Output

The total Products are: 600
Note : The above home + office statement is equivalent to home.__add__(office) .

Example 2: Overload the > operator for custom class object

Similar to the addition overloading, we can overload the greater than > operator with __gt__() method.

class Products:
    def __init__(self, items):
        self.items = items

    #here self is the object on the left side of + operator
    # and other is the object on the right side of the + operator
    def __gt__(self, other):
        return self.items > other.items

home = Products(200)

office = Products(400)

print("home > office = ", home > office)

Output

home > office =  False

Conclusion

Polymorphism in Python allows performing method overriding and operator overloading, and it is one of the important properties of Object-Oriented Programming. With Polymorphism, an operator can have multiple behaviors with various data types or overload the operator's default behavior.

In this tutorial, we discussed Polymorphism in Python with the help of some examples. If you like this article or have any questions, please share your comments in the comment section down below.

People are also reading:

FAQs


It lets us perform a single task in multiple ways.

Method overloading is the run-time polymorphism.

No, Python does not support function overloading.

There are two types of polymorphism in OOPs: 1. Static Binding or Compile-Time Polymorphism 2. Dynamic Bindin or Runtime Polymorphism.

An example of compile-time polymorphism is method overloading, while an example of runtime polymorphism is method overriding.

Leave a Comment on this Post

0 Comments