Polymorphism is one of the four fundamental OOPS concepts. The other three being Inheritance, Encapsulation, Abstraction
Polymorphism is a Greek word where poly means many and morph means change thus it refers to the ability of an entity taking many forms. In an object oriented context that means an entity which may be a method, object or operator can represent different types based on the scenario where they are used.
Polymorphism in Python
In an object oriented language you will find support for Polymorphism through-
- Method overloading
- Method overriding
- Operator overloading
Python being an object oriented language also supports Polymorphism but only through Method overriding and operator overloading. Method overloading in its traditional sense is not supported in Python.
Apart from these ways you will also find support for Polymorphism in Python through duck typing. If there is an object that can fly and quack like a duck then it must be a duck, this is the duck typing principle followed in Python.
In this post we’ll see examples of polymorphism in Python through all these options.
Python Polymorphism example- Method overloading
Method overloading in its traditional sense, where you can have more than one method having the same name with in the class where the methods differ in types or number of arguments passed, is not supported in Python.
Trying to have methods with same name won’t result in compile time error in Python but only the last defined method is recognized in such scenario, calling any other overloaded method results in an error.
- Refer Method Overloading in Python to know more about method overloading in Python.
But you can still simulate polymorphism through method overloading by using default arguments in a method. In the example there is one default argument in the method sum. If the method is called with 2 parameters for the third default value is used. If the method is called with 3 parameters passed value is used for the third parameter.
class OverloadDemo: # sum method with one default parameter def sum(self, a, b, c=0): s = a + b + c return s od = OverloadDemo() #calling method with 2 args sum = od.sum(7, 8) print('sum is-', sum) #calling method with 3 args sum = od.sum(7, 8, 9) print('sum is-', sum)
Output
sum is- 15 sum is- 24
Polymorphism through inheritance- Method overriding
Method overriding provides ability to change the implementation of a method in a child class which is already defined in one of its super class. If there is a method in a super class and method having the same name and same number of arguments in a child class then the child class method is said to be overriding the parent class method.
- Refer Method Overriding in Python to know more about method overriding in Python.
When the method is called with parent class object, method of the parent class is executed. When method is called with child class object, method of the child class is executed. So the appropriate overridden method is called based on the object type, which is an example of Polymorphism.
Polymorphism through inheritance example
class Person: def __init__(self, name, age): self.name = name self.age = age def displayData(self): print('In parent class displayData method') print(self.name) print(self.age) class Employee(Person): def __init__(self, name, age, id): # calling constructor of super class super().__init__(name, age) self.empId = id def displayData(self): print('In child class displayData method') print(self.name) print(self.age) print(self.empId) #Person class object person = Person('John', 40) person.displayData() #Employee class object emp = Employee('John', 40, 'E005') emp.displayData()
Output
In parent class displayData method John 40 In child class displayData method John 40 E005
In the example when the displayData() method is called with Person class object, displayData() of the Person class is executed. When displayData() method is called with Employee class object, displayData() of the Employee class is executed.
Polymorphism through operator overloading
Operator overloading means the ability to overload the operator to provide extra functionality in addition to its real operational meaning. Operator overloading is also an example of polymorphism as the same operator can perform different actions.
- Refer Operator Overloading in Python to know more about operator overloading in Python.
For example ‘+’ operator which is used with numbers to perform addition operation. But ‘+’ operator when used with two strings concatenate those Strings and merge two lists when used with lists in Python.
#using + operator with integers to add them print(5 + 7) #using + operator with Strings to concatenate them print('hello ' + 'world') a = [1, 2, 3] b = [4, 5, 6] # using + operator with List to concatenate them print(a + b)
Output
12 hello world [1, 2, 3, 4, 5, 6]
You can also overload operators to provide functionality for custom class objects. For all operators internally Python defines methods to provide functionality for those operators. For example functionality for ‘+’ operator is provide by special method __add__(). Whenever ‘+’ operator is used internally __add__() method is invoked to do the operation.
When you want any operator to work with custom objects you need to override the corresponding special method that provides functionality for that operator.
Overloading ‘+’ operator to work with custom objects
class Point: def __init__(self, x, y): self.x = x self.y = y #overriding magic method def __add__(self, other): return self.x + other.x, self.y + other.y p1 = Point(1, 2) p2 = Point(3, 4) print(p1+p2)
Output
(4, 6)
Duck typing in Python
Python though strongly typed is also dynamically typed so the type of any object/field is implicitly assigned depending on where and how the field is used.
If there is an object that can fly and quack like a duck then it must be a duck, this is duck typing principle followed in Python.
When you invoke a method using an object type of the object is not checked in Python. You can use any object to invoke a method as long as that method is there to be invoked.
class Duck: def sound(self): print('Quack Quack') class Cat: def sound(self): print('Meow Meow') class Human: def sound(self): print('Hey hello') class Test: def invoke(self, obj): obj.sound(); t = Test() obj = Duck() t.invoke(obj) obj = Cat() t.invoke(obj) obj = Human() t.invoke(obj)
Output
Quack Quack Meow Meow Hey hello
When the object of type Cat is passed to the invoke() method and sound() method is called using that object, sound() method of class Cat is executed. When object of type Duck is passed to the invoke() method and sound() method is called using that object, sound() method of class Duck is executed and same for object of type Human.
As evident from the example because of the duck typing philosophy of Python you are getting run time polymorphism inbuilt with in the language, based on the passed object correct method is invoked at runtime.
That's all for this topic Polymorphism in Python. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Python Tutorial Page
Related Topics
You may also like-