Everything a Beginner Should Know About Polymorphism in Python[With Examples]

Prashant Last Updated : 14 Oct, 2024
7 min read

Introduction

Assume there is a class called animal, but within that class, there are numerous forms such as dog, cat, and cow. That is, a common class animal consists of a variety of forms that come in a variety of shapes and sizes and perform a variety of functions. This entire phenomenon is defined by a single term: polymorphism. Polymorphism in python is a term used to refer to an object’s ability to take on multiple forms. The term is derived from two distinct terms: poly, which means numerous, and morphs, which means forms.

Polymorphism

This article was published as a part of the Data Science Blogathon

Class and Objects

A class is a template for creating an object. In the following example, we create a class named-A and declare a variable x, which is then passed a value. The object x is created and the value of x is printed.

A simple example demonstrating the concept of class and object in Python:-

class A:
  x = 5
object = A()
print(object.x)

Constructor

A constructor is a sort of subroutine in object-oriented programming. When an object is created within a class, the function constructor is used to assign values to data members. Almost every time we create an object in Python, we use the __init__() function. We use the __init__() function almost everywhere in polymorphism.

What is Polymorphism in Python?

Polymorphism is a term used in Python to refer to a generic function name that may be used for several kinds. This notion is commonly used in Python’s object-oriented programming. As is the case with other programming languages like as Java and C++, polymorphism is implemented in Python for a variety of purposes, most notably Duck Typing, Operator and Method overloading, and Method overriding. This polymorphism may be accomplished in two distinct ways: overloading and overriding.

Polymorphism in Python

 

A straightforward demonstration of polymorphism in Python:-

>>>4+5
9
>>>"4"+"5"
45
>>>"ab"+"cd"
abcd

We can see from the above example that the addition operator is utilized in a variety of ways. In the first example, since the data given is two integer values, the operator performed a two-number addition.

And in the second example, the identical values are supplied as string data and the same operator concatenates the two strings (concatenation is the act of joining two strings end-to-end). In the third example, the data is two strings, but the operator is identical to the previous one, and it concatenates the two strings.

>>>"3"+"ab"
3ab

Although the first value is an integer, the addition operator concatenated the two texts in this case.

Thus, these were some of the most fundamental instances of polymorphism in Python.

Types of Polymorphism in Python

Two Types of Polymorphism in Python

Duck Typing

Objects are used based on their abilities (methods) and can be of different classes as long as they share the same methods. This is achieved through method overriding in inheritance.

Limited Operator Overloading:

Special methods like __add__ allow for custom behavior when using operators (+, -, etc.) with your objects.

How to use polymorphism in Python?

Overloading

Overloading may be classified into two categories.

  • Operator Overloading
  • Method Overloading

Operator Overloading

Operator overloading is a kind of overloading in which an operator may be used in ways other than

those stated in its predefined definition.

Thus, in the first example, the multiplication operator multiplied two numbers; but, in the second, since

multiplication of a string and an integer is not feasible, the character is displayed three times twice.

Thus, it demonstrates how a single operator may be used in a variety of ways.

Overloading operators in practice

Example 1:
class Vehicle:
    def __init__(self, fare):
        self.fare = fare
bus= Vehicle(20)
car= Vehicle(30)
total_fare=bus+ car
print(total_fare)
Output:
Traceback (most recent call last):
File “G:рythоn рyсhаrm рrоjeсtmаin.рy”, line 7, in
    total_fare=bus+ car
TypeError: unsupported operand type(s) for +: ‘Vehicle’ and ‘Vehicle’

In the above example, an error occurred because Python is unable to combine two objects. In

this case, the item is a vehicle.

Now comes the time for operator overloading to be used.

Now we are going to overload the specific method __add__ operator.

class Vehicle:
def __init__(self, fare):
self.fare = fare
def __add__(self, other)://using the special function __add__ operator
return self.fare+ other.fare
bus= Vehicle(20)
car= Vehicle(30)
total_fare=bus+ car
print(total_fare)
Output:
50

By overloading the special function, we declare that whenever we use the plus operator in the object

total_fare=bus+car, their fares will be added.
Example 2: In this example, let us compare the fares of several modes of transport.
class Vehicle:
    def __init__(self, fare):
        self.fare = fare
    def __lt__(self, other):// relational operator  __lt__ is used here as the special function
        return self.fare< other.fare

bus= Vehicle(10)
car= Vehicle(30)
compare=bus< car
print(compare)
Output:
True

In the above example, the relational operator __lt__ is utilized as a special function to enable the operator Overloading.

Method Overloading

Overloading a method refers to a class that has many methods with the same name but perhaps distinct parameters. While Python does not natively enable method overloading, there are numerous techniques to do this. While method overloading is possible, only the most recently specified methods are usable.

Let’s try to understand with the help of an example

Assume a class A, within the class we have taken a function show which has a constructor self and arguments with the default value None and None. Then I created an object and executed the function with the object obj.show, but I didn’t supply any arguments, despite the fact that it would display None and None since we set default values in the function area.

Example:
class A:
def show(self, a=None, b=None):
print(a,b)
obj=A()
obj.show()
Output:
None None

To supply another value, I must now use another method obj.show() with an argument.

Example:
class A:
def show(self, a=None, b=None):
print(a,b)
obj=A()
obj.show()
obj.show(4)
Output:
None None
4 None

The None value supplied to an in the function portion is substituted with 4 in the output. Part 4 is given as an argument to the function call.

Now, let’s examine what happens if we send two arguments to the function call in the following example.

Example:
class A:
def show(self, a=None, b=None):
print(a,b)
obj=A()
obj.show()
obj.show(4)
obj.show(4,5)
Output:
None None
4
4 5

Due to the fact that we sent two parameters 4 and 5 during the function call, two distinct values for a and b are allocated.Thus, in the preceding example, we saw how we may utilize the same method and call distinct functions in a variety of ways.Consider another example in which we utilized conditional statements to invoke several functions in distinct ways.

Example:
class Area:
    def find_area(self, a=None, b=None):
        if a != None and b != None:
            print("Rectangle:", (a * b))
        elif a != None:
            print("square:", (a * a))
        else:
            print("No figure assigned")
obj1=Area()
obj1.find_area()
obj1.find_area(10)
obj1.find_area(10,20)
Output:
No figure assigned
square: 100
Rectangle: 200

If no arguments are supplied during the function call, no value is assigned; if a single argument is passed, the area of a square is shown; and if two values are passed, the area of a rectangle is displayed.

Inheritance

Before we get into method overriding, it’s necessary to understand Python’s initial inheritance. Inheritance is the method by which a class may be derived from any base class, with the derived class inheriting all of the base class’s attributes. Inheritance alleviates the challenge of repeatedly writing the same code and enhances reusability.

Example of inheritance:
class Bird://base class Bird
    def sound(self):
        print("Birds Sounds")
#сhild сlаss Dоg inherits the bаse сlаss Аnimаl
class Sparrow(Bird)://child class Sparrow
    def tweet(self):
        print("sparrow tweeting")
d = Sparrow()
d.tweet()
d.sound()
Output:

Sparrow tweeting
Birds Sound

Method Overriding

Method overriding is the process of changing a base class using the methods and parameters of a derived class.

Consider an example to demonstrate how it works. To begin, we’ll design a base class containing a method and then a derived class devoid of methods.

Example:
class Vehicle:
    def run(self):
        print("Saves Energy")
class EV(Vehicle):
    pass
ev = EV()
ev.run()

As a result, when the function is invoked, the output will display the method of the base class, since the derived class lacks a method.

Output:
Saves Energy

Now, in the following example, we define another method with the same name as the base class but with a different parameter under the derived class. Due to the fact that the base class’s method has been overridden by the derived class, the output will include just the derived class’s method.

Example:
class Vehicle:
    def run(self):
        print("Saves Energy")
class EV(Vehicle):
    def run(self):
        print("Run on Electricity")
ev = EV()
ev.run()
Output:
Run on Electricity
Super() Function

Due to the fact that the base class’s method has been overridden, the base class’s method cannot be invoked normally. Thus, in order to invoke the base class method, we must utilize the super function in the overridden method of the derived class.

Example:
class Vehicle:
    def run(self):
        print("Saves Energy")
class EV(Vehicle):
    def run(self):
    super().run()//super function is used to call the method of base class 
        print("Run on Electricity")
ev = EV()
ev.run()
Output:
Saves Energy
Run on Electricity

Duck Typing

Duck typing is a polymorphism notion. The term duck typing is derived from a proverb that says

Duck typing is a polymorphism notion. The term duck typing is derived from a proverb that says everything that walks like a duck quacks like a duck, and swims like a duck is referred to like a duck regardless of the item. In basic terms, it indicates that if anything matches its behavior to another, it will be considered a member of the category to which it belongs.

Why is polymorphism needed?

When discussing object-oriented programming in Polymorphism in python, the word polymorphism is unavoidably used. In object-oriented programming, objects must take on a variety of shapes. This characteristic is critical in software development. The same action may be executed in a variety of ways because of polymorphism. This notion is often used while discussing loose coupling, dependency injection, and interfaces, among other things.

Conclusion

Polymorphism in Python offers versatility through different types like Duck Typing, Limited Operator Overloading, and various techniques like Overloading, Operator Overloading, Method Overloading, Inheritance, and Method Overriding. It’s vital for flexible, reusable code, allowing objects to be treated interchangeably, and enhancing code readability and maintainability.

Frequently Asked Questions

Q1. What is polymorphism in programming?

Polymorphism in programming means objects can do different things based on how they’re used. In Python, it lets different types of objects work together if they have similar traits.

Q2.What is polymorphism encapsulation and inheritance in Python?

In Python, polymorphism is like having objects in a box (encapsulation) and sharing traits (inheritance). Encapsulation keeps things organized, and inheritance lets objects borrow traits from others.

Q3.What is overloading and overriding in Python polymorphism?

In Python, overloading means having different versions of a function with the same name but different arguments. Overriding happens when a subclass changes how a method works that it got from its parent class. It helps objects act differently based on their type.


The media shown in this article is not owned by Analytics Vidhya and are used at the Author’s discretion.

Hello, my name is Prashant, and I'm currently pursuing my Bachelor of Technology (B.Tech) degree. I'm in my 3rd year of study, specializing in machine learning, and attending VIT University.

In addition to my academic pursuits, I enjoy traveling, blogging, and sports. I'm also a member of the sports club. I'm constantly looking for opportunities to learn and grow both inside and outside the classroom, and I'm excited about the possibilities that my B.Tech degree can offer me in terms of future career prospects.

Thank you for taking the time to get to know me, and I look forward to engaging with you further!

Responses From Readers

Clear

We use cookies essential for this site to function well. Please click to help us improve its usefulness with additional cookies. Learn about our use of cookies in our Privacy Policy & Cookies Policy.

Show details