Polymorphism in Python Programming
OOPs in Python
In this lesson, we will understand what is Polymorphism in Python and how to implement them in programming along with some examples.
What is Polymorphism in Python?
The term Polymorphism has been derived from the words poly means many and morphism means form. In programming, polymorphism means to create many forms from one.
There are three types of polymorphism available in python and they are:
- Method Overloading
- Method Overriding
- Operator Overloading
Let's discuss each of them in detail one by one.
Method Overloading
Method Overloading is a process in which we declare a method that can perform a different task when provided with a different number of inputs.
For example, we will overload a method called area, which, when called with one argument, will display the area of a square. When the same method is called with two arguments, it will display the area of a rectangle.
Example of Method Overloading
class Shape:
def area(self, x=None, y=None):
if x!=None and y==None:
print('Area of a square = %.2f' %(x*x))
elif x!=None and y!=None:
print('Area of a rectangle = %.2f' %(x*y))
x = Shape()
x.area(10)
x.area(10,5)
Output
Area of a square = 100.00 Area of a rectangle = 50.00
In the above program, None is a default value for the arguments x and y. When we call the method with one argument, it checks if the value of argument x is not None and the value of argument y is None. If both conditions are true, it prints a square's area.
On the other hand, when we call the method with two arguments, it checks if the value of both the arguments x and y is not None. If the conditions are true, it prints the rectangle's area.
Method Overriding
Method Overriding is a process used in inheritance in which a base class method is redeclared with a new body in a subclass.
Example of Method Overriding
class Student:
def display(self):
print('Roll: 1')
print('Name: Thomas')
class Marks(Student):
# Overriding the display method of base class in subclass
def display(self):
print('English: 82')
print('Maths: 94')
print('Computer: 88')
x = Marks()
x.display()
Output
English: 82 Maths: 94 Computer: 88
In the above program, we have created a method called display in the base class Student that prints the roll and name of a student on the screen. On the other hand, we have created another class called Marks that inherits the base class Student. In the subclass Marks, we have overridden the method display of the base class with a new body that prints the marks of three subjects on the screen.
Operator Overloading
Operator Overloading is a process in which we define a new action for an existing operator.
For example, + operator is used for adding two or more numbers. We can define a new action for the + operator so that it can add values stored inside two objects. Doing so means that we have overloaded the + operator.
In python, each operator is associated with an internal method that operates when we use the operator.
For example, + operator is associated with the internal method __add__(self, other), sometimes called the magic method. So when we use the + operator on two variables, say x, y, to find its sum, the magic method of the + operator gets invoked on these variables as x.__add__(y).
List of operators and their magic methods in python
Operator | Name | Magic Method |
+ | Addition | __add__(self, other) |
- | Subtraction | __sub__(self, other) |
* | Multiplication | __mul__(self, other) |
/ | Division | __div__(self, other) |
// | Floor Division | __floordiv__(self, other) |
% | Modulus Division | __mod__(self, other) |
** | Power | __pow__(self, other) |
+= | Add and Assign | __iadd__(self, other) |
-= | Subtract and Assign | __isub__(self, other) |
*= | Multiply and Assign | __imul__(self, other) |
/= | Divide and Assign | __idiv__(self, other) |
//= | Floor Divide and Assign | __ifloordiv__(self, other) |
%= | Modulus Divide and Assign | __imod__(self, other) |
**= | Power and Assign | __ipow__(self, other) |
< | Less than | __lt__(self, other) |
<= | Less than or equal to | __le__(self, other) |
> | Greater than | __gt__(self, other) |
>= | Greater than or equal to | __ge__(self, other) |
== | Equal to | __eq__(self, other) |
!= | Not equal to | __ne__(self, other) |
Overloading + Operator
class Data:
def __init__(self, a=0, b=0):
self.x = a
self.y = b
def __add__(self, other):
a = self.x + other.x
b = self.y + other.y
return a, b
d1 = Data(10, 20)
d2 = Data(30, 40)
d3 = d1 + d2
print(d3)
Output
(40, 60)
In the above program, we have overloaded the + operator to find the sum of values stored in two objects. Here d1 and d2 are the two objects of class Data. When we call the + operator on d1 + d2 it invokes the __add__(self, other) magic method as d1.__add__(d2). Where self points to the d1 object and other points to the d2 object. Then using self and other as a reference to the objects d1 and d2, we store the sum of their variables in a and b and then return these variables as output.
Overloading += Operator
class Data:
def __init__(self, a=0, b=0):
self.x = a
self.y = b
def __iadd__(self, other):
self.x = self.x + other
self.y = self.y + other
return self
def display(self):
print('x=%d' %(self.x))
print('y=%d' %(self.y))
d1 = Data(10, 20)
d1.display()
d1+=2
d1.display()
Output
x=10 y=20 x=12 y=22
Overloading > Operator
class Data:
def __init__(self, a=0):
self.x = a
def __gt__(self, other):
a = self.x > other.x
return a
d1 = Data(18)
d2 = Data(11)
if d1>d2:
print('Value of d1 is greater than value of d2')
else:
print('Value of d1 is not greater than value of d2')
Output
Value of d1 is greater than value of d2