Polymorphism in Python (with Example)

Polymorphism is one of the most important object-oriented programming feature in Python. It allows objects to take multiple forms or behaviors based on the context in which they are used.

The word polymorphism is derived from two Greek words, poly and morphism. Here, poly means “many” and morphism means “forms”. So, the word polymorphism means “many forms”. That is, one entity that can take many forms. Let’s understand it with some simple real-time examples.

There are several real-time examples of polymorphism in the world. They are as follows:

(1) We all know that water occurs in a liquid form, but it changes to solid when it is frozen, and it changes to a gas when it is heated at its boiling point.

(2) The best real-time example of polymorphism is human behavior. One person can have different behavior. For example, a person acts as an employee in the office, a customer in the shopping mall, a passenger in bus/train, a student in school, and a son at home.

(3) We all use a single power button to switch ON and OFF the computer system.

Similarly, polymorphism is a feature in OOP by which we can perform a single task in different ways. The ability of the method or operator to behave in more than one form is called polymorphism in Python.

In other words, when the same function/method or an operator behaves differently in accordance with the data provided to it, it is called polymorphism. In polymorphism, a single entity (method, operator, or object) behaves different types in various scenarios.

Polymorphism allows the same method to be called on different objects, resulting in different behaviors based on the type of object. With polymorphism, we can achieve flexibility, reusability, and extensibility in our code because we can perform various operations by using the same method or operator according to requirements.

Types of Polymorphism in Python


In Python, there are mainly two types of polymorphism. They are as:

  • Compile-time polymorphism
  • Run-time polymorphism

Types of polymorphism in Python

(1) Compile-time Polymorphism: This type of polymorphism is also known as static polymorphism. We can achieve or implement this type of polymorphism through function or method overloading and operator overloading.


(2) Run-time Polymorphism: This type of polymorphism is also referred to as dynamic polymorphism. We can achieve this type of polymorphism through inheritance and method overriding.

Polymorphism through Method Overloading


Method overloading is an object-oriented programming feature by which we can implement polymorphism. In method overloading, we define multiple methods with the same name, but with a different type or number of arguments. But Python does not support the method overloading directly because two methods can’t have the same name in Python.

If we define two instance methods with the same name in a Python program, there will be no syntax error. Python will simply replace the first one with the second one. One way to implement method overloading in Python is by setting a default value to the arguments in the method definition.

However, this is no prefect way to implement method overloading, but it works. Here is a simple example of implementing the method overloading inside a class in Python.

Example 1:

# Define a class Calculator.
class Calculator:
    def add(self, a, b, c = 0):
        return a + b + c

# Create an instance of class Calculator.
calc = Calculator()

# Call add() method using reference variable calc by passing differnt number of arguments.
# Store the results into variables result1 and result2.
result1 = calc.add(1, 2)      # Calls add with 'c' defaulting to 0.
result2 = calc.add(1, 2, 3)   # Calls add with 'c' set to 3.

# Display the results on the console.
print(result1)
print(result2)
Output:
       3
       6

In this example, we have called the add() method with two or three arguments. If only two arguments are provided, the default value of c is used, making it possible to achieve the method overloading in Python.

Polymorphism through Method Overriding


Method overriding is a concept of having the same method name in a derived class as in the base class. With inheritance and method overriding, we achieve the runtime polymorphism. In Python, method overriding occurs when a derived class offers a different implementation for a method that is already defined in its base class.


The purpose of method overriding is to change the behavior or functionality of the method based on the requirements of derived class. The behavior of a method is determined at runtime based on the actual type of object. It can differ for different instances of the derived classes, providing flexibility and adaptability in our code.

Here is a simple example of achieving or implementing runtime polymorphism through method overriding in Python as:

Example 2:

# Define a base class.
class Shape:
    def area(self):
        pass

# Define derived classes.
class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side * self.side

class Rectangle(Shape):
    def __init__(self, length, breadth):
        self.length = length
        self.breadth = breadth

    def area(self):
        return self.length * self.breadth

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius * self.radius

# Outside the class definition.
sq = Square(20)
rc = Rectangle(10, 20)
cr = Circle(3)

# Calling the overriding methods of derived classes.
print("Area of square: ", sq.area())
print("Area of rectangle: ", rc.area())
print("Area of circle: ", cr.area())
Output:
       Area of square:  400
       Area of rectangle:  200
       Area of circle:  28.259999999999998

In this example, we have defined a base class named Shape and three derived classes named Shape, Rectangle, and Circle, respectively. Each class has an instance method called area() that calculates area. The derived classes Shape, Rectangle, and Circle inherit from the Shape class and override the area() method.

Then, we have created an object of each derived class and call the area() method on it. As you can observe, although the area() method is called on an object of each class, the output is different, demonstrating the concept of polymorphism.

Polymorphism in Addition Operator


We extensively use the addition (+) operator in the Python program. But, it has not only a single usage. For example, the addition operator behaves differently when used with different data types. Here is an example based on it:

Example 3:

num1 = 20
num2 = 30
print(num1 + num2)

str1 = "Python"
str2 = " Programming"
print(str1 + str2)
Output:
       50
       Python Programming

In this example, we have used the addition operator (+) to perform the arithmetic operation on integer data type. But, when used with two strings, the addition operator concatenates (joins) the strings together. Similarly, we can also use the addition operator for list concatenation, which combines the elements of two lists into a single list.

Thus, we can use a single plus operator to carry out different operations for distinct data types. This is the most simple and basic occurrence of polymorphism in Python.

Polymorphism with Class Methods in Python


As we know that polymorphism is one of the most important object-oriented programming feature. We can use this feature while constructing class methods. In Python, it is possible to define different classes with methods having the same name.

Later, we can then generalize calling these methods by irrespective of the object we are working with. This is called class polymorphism in Python. Let’s look at an example program based on it.

Example 4:

class Jharkhand:
    def capital(self):
        print("Ranchi")
    def language(self):
        print("Hindi and English")

class Bihar:
    def capital(self):
        print("Patna")
    def language(self):
        print("Hindi and English and Bhojpuri")

# Creating objects.
obj1 = Jharkhand()
obj2 = Bihar()

# Use for loop to access different objects.
for state in (obj1, obj2):
    state.capital()
    state.language()
Output:
       Ranchi
       Hindi and English
       Patna
       Hindi and English and Bhojpuri

In this example, we have defined two classes named Jharkhand and Bihar. They share the same structure and have the same method names: capital() and language(). Now you observe in this code that we have not created a common base class or linked classes together in any way. Still, we can pack these two distinct objects in a tuple and iterate through it using a common variable named state. This is possible only with the help of polymorphism in Python.

Polymorphism with Duck Typing


In Python, duck typing is a dynamic typing concept where the focus is on the behavior of an object rather than its type. Let’s take an example based on the duck typing.

Example 5:

class Dog:
    def speak(self):
        return "Woof!"

class Cat:
    def speak(self):
        return "Meow!"

def make_sound(animal):
    print(animal.speak())

# Creating objects.
dog = Dog()
cat = Cat()

make_sound(dog)
make_sound(cat)
Output:
       Woof!
       Meow!

In this example code, we have defined two classes named Dog and Cat. Both classes have a speak() method that returns a sound they make. However, Dog and Cat are not related classes. Even then, they can be treated interchangeably if they have the same method names. This concept enables us to write a generic code that can work with any object that has a speak() method.

In the above code, the make_sound() method takes an object as an argument and invokes its speak() method. We have passed both Dog and Cat objects to the method because they have a speak() method, even though they belong to the distinct classes.

Function Polymorphism in Python


There are some built-in functions in Python which are compatible to be run with more than one data types. For example, the built-in len() function, which can run with many data types in Python. Let’s look at an example program based on this.

Example 6:

# Python program to illustrate the polymorphism in len() function.
# This statement will determine the length of the string.
print(len("Python Programming"))

# This statement will determine the number of items.
print(len(["Java", "HTML", "Python", "JavaScript"]))

# This statement will determine the total number of keys.
print(len({"Name": "Deepak", "Address": "Dhanbad"}))
Output:
       18
       4
       2

In this example program, we are using different data types such as string, list, set, and dictionary with the built-in len() function. This is an example of function polymorphism in Python.

Polymorphism with Functions and Objects


Python provides a facility to define a function that can take any object or instance allowing for implementing polymorphism. Let’s understand it with the help of an example program.

Example 7:

# Python program to demonstrate the polymorphism with functions and objects.
# Create a class named India.
class India():
    def capital(self):
        print("New Delhi is the capital of India.")
    def language(self):
        print("Hindi and English are the most widely spoken languages of India.")
    def type(self):
        print("India is a developing nation.")

# Create a class named USA with the same method names as in the class India.
class USA():
    def capital(self):
        print("Washington, D.C. is the capital of USA.")
    def language(self):
        print("English is the primary language of USA.")
    def type(self):
        print("USA is a developed country.")

# Define a function called 'func' that takes an object 'obj' as an argument
def func(obj):
  # Call methods of the provided object.
    obj.capital()
    obj.language()
    obj.type()

# Create an instance of the 'India' class and store it in 'obj_ind'.
obj_ind = India()
# Create an instance of the 'USA' class and store it in 'obj_usa'.
obj_usa = USA()

# Call the 'func' function with 'obj_ind' as the argument.
func(obj_ind)
# Call the 'func' function with 'obj_usa' as the argument.
func(obj_usa)
Output:
       New Delhi is the capital of India.
       Hindi and English are the most widely spoken languages of India.
       India is a developing nation.
       Washington, D.C. is the capital of USA.
       English is the primary language of USA.
       USA is a developed country.

In this example code, we have defined two classes named “India” and “USA”. Both classes have methods ‘capital’, ‘language’, and ‘type’. These methods provide information about the capital, languages, and the development status of the respective countries. Then, we have defined a function named ‘func’ that takes an object ‘obj’ as its argument. With this object obj, we have called capital(), language(), and type() methods.

After that, we have created instances of classes India and USA, respectively. Then, we have called func() function using object reference variable “obj_ind” and “obj_usa”, respectively. As a result, it prints information about the capital, languages, and development status of both India and the USA.

Advantages of Polymorphism


There are several benefits of polymorphism in python programming. They are as:

(1) Code Reusability: Polymorphism allows us to write common code that can work with objects of distinct classes. This promotes the code reusability and code duplication.

(2) Flexibility: Polymorphism offers flexibility in the code by allowing objects of distinct classes to be used interchangeably. This flexibility makes the code more adaptable to changes and promotes modularity.

(3) Extensibility: Polymorphism promotes extensibility by allowing us to add new classes and objects without modifying the existing code.

(4) Simplified Design: Polymorphism simplifies the overall design of complex systems by abstracting away the specialized details of objects. It allows us to concentrate on the common behaviors shared by objects, which, in turn, leads to cleaner, more maintainable, and easier-to-understand code.


In conclusion, polymorphism is a powerful feature in Python programming. It allows objects of different classes to be treated as objects of a common base class. It promotes code reusability, flexibility, extensibility, and ease of development, making it an essential tool in Python’s object-oriented programming paradigm.

By understanding and leveraging polymorphism, we can write more efficient and maintainable code. Hope that you will have understood the basic concepts of polymorphism in Python and practiced all example programs. In the next, we will understand how to implement or achieve abstraction in Python
Thanks for reading!!!