Polymorphism in Python

Polymorphism in Python

Welcome to another chapter of our Python tutorial series, Learn Python with me. We will discuss the Polymorphism in Python in this post.


Links to all chapters of Python: Learn Python


Polymorphism in Python

The word Polymorphism is derived from two words from the Greek language, poly and morphus. Poly means many, and morphus means forms in Greek. If we can show anything in various forms, that’s Polymorphism in layman’s terms. 

Let us take the example of water in daily life. Using water, you can make juices, cold drinks or iced tea. The same water behaves differently in each form, right? That is Polymorphism.

Polymorphism in Python

Similarly, a method, object or variable can behave differently in programming based on each context. If any method or variable shows different behaviour in different circumstances, it is called Polymorphism. We have an in-built Polymorphism in Python language. The topics mentioned below are typical cases of Polymorphism in Python.

  • Duck Typing Philosophy in Python 
  • Operator Overloading 
  • Method Overloading 
  • Method Overriding

Duck Typing Philosophy in Python

You probably know by now that we don’t declare the type of variables explicitly in Python. That doesn’t mean the variables in Python do not have a type. Python takes care of assigning the type implicitly. Smart, isn’t it?

#python program to show the implicit type declaration
a = 7
print("Type of a: ",type(a))

a = "Python"
print("Type of a: ",type(a))
Output

Type of a:  <class 'int'>
Type of a:  <class 'str'>

From the program mentioned above, it is evident that the Python takes care of type declarations implicitly and dynamically in a strong manner. Therefore, the variables that point to the memory of the location of the data are not bothered about the data it is going to store. 

Duck typing is a term used in dynamic programming languages that support Polymorphism. The idea of this concept is that the code does not care whether each object is a duck. All it takes care of is which object is quacking. Let us look at one more program to understand how it affects methods.

#duck typing example 
class Cat:
  def meow(self):
    print("Meow, meow!")

#Duck class with talk() method
class Duck:
  def talk(self):
    print("Quack, quack!")

#Person class with talk() method
class Person:
  def talk(self):
    print("Hello I am a Person")

#a method that receives an object and calls talk() method
def call_talk(obj):
  obj.talk()

#call call_talk method and pass object to it
#based on the type of object, talk() method gets executed

a = Duck()
call_talk(a)
a = Person()
call_talk(a)
a = Cat()
call_talk(a) #throws an error in this line
Output

Quack, quack!
Hello I am a Person

Traceback (most recent call last):
  File "/home/aatmann/Documents/iSapna/Python/InherPoly/duck1.py", line 28, in <module>
    call_talk(a) #throws an error in this line
  File "/home/aatmann/Documents/iSapna/Python/InherPoly/duck1.py", line 18, in call_talk
    obj.talk()
AttributeError: 'Cat' object has no attribute 'talk'

In the above program, we tried passing the object of the Cat class to the call_talk() method. Since the Cat class does not have a talk() method, it ends up throwing an error. 

You can also notice that it successfully accepted the objects of both Duck and Person classes since they have the talk() method in them. And call_talk() method did not care about which talk() method it would execute. That’s the whole point of Duck Typing philosophy in programming. 

As mentioned above, all it cares about is which method is quacking, and it does care whether each method is a duck or not. Yes, you got it right. You’d need a method that can quack.

Operator Overloading

When an operator exhibits different behaviour in various situations, it is called operator overloading. For instance, we can use the operator ‘+‘ to add two numbers and concatenate two strings simultaneously.

#Python program to showcase
#Operator overloading
#using on numbers
a = 7
b = 3
print(a+b)

#using on strings
string1 = 'Hello'
string2 = ' How, are you?'
print(string1+string2)

#using on lists to combine into single list
lst1 = [1,2,3]
lst2 = [4,5,6]
print(lst1 + lst2)
Output

10
Hello How, are you?
[1, 2, 3, 4, 5, 6]
aatmann@isapna:~/Do

You can notice from the program above that the operator ‘+‘ behaved differently in three different scenarios.

Method Overloading

When we define a method that can handle more than one task, it is called Method Overloading.

class Human:
  def sayHello(self, name = None):
    if name is None:
      print("Hello")
    else:
      print("Hello {}".format(name))

person = Human()
person.sayHello()
person.sayHello("Karthik")
Output

Hello
Hello Karthik

In the example program above, we defined a method that can accept either one parameter or no parameter. And it behaves differently in both scenarios, as shown in the output. This is called Method overloading.

Method Overriding

We discussed this concept already in the previous chapter. When a method from the parent class gets overridden by a method with the same name from the child class, it is called method overriding.

#Python program to show
#Method overriding
import math
class Square:
  def area(self,radius):
    print("Area of square: ",radius**2)
class Circle(Square):
  def area(self,radius):
    print("Area of circle: {}".format(math.pi*(radius**2)))

obj = Circle()
obj.area(7)
Output

Area of circle: 153.93804002589985

We created an object for the class Circle in the program above. You can notice that the class Circle inherits the methods and attributes from the class Square. However, the method area from the class Square gets overridden by the method with the same name in the class Circle. This is called method overriding, and this program is an excellent example of Polymorphism and Inheritance.

Source

Scroll to Top