Tuesday, March 22, 2022

Polymorphism

In OOP, polymorphism is the ability of an instance to behave in multiple ways and a way to use
the same method with the same name and the same arguments, to behave differently in accordance with the class it belongs to.

Polymorphism can be implemented in two ways: method overloading and method overriding. Let us discuss each of them.

Method overloading

Method overloading is a way to achieve polymorphism by having multiple methods with the same name, but with a different type or number of arguments. There is no clean way to implement method overloading in Python. Two methods cannot have the same name in Python. In Python, everything is an object, including classes and methods. When we write methods for a class, they are in fact attributes of a class from the namespace perspective and thus cannot have the same name. If we write two methods with the same name, there will be no syntax error, and the second one will simply replace the first one.

Inside a class, a method can be overloaded by setting the default value to the arguments. This is not the perfect way of implementing method overloading, but it works. Here is an example of method overloading inside a class in Python:

#methodoverloading1.py
class Car:
def __init__(self, color, seats):
self.i_color = color
self.i_seat = seats
def print_me(self, i='basic'):
if(i =='basic'):
print(f"This car is of color {self.i_color}")
else:
print(f"This car is of color {self.i_color} \

with seats {self.i_seat}")
if __name__ == "__main__":
car = Car("blue", 5 )
car.print_me()
car.print_me('blah')
car.print_me('detail')

In this example, we add a print_me method with an argument that has a default value. The default value will be used when no parameter will be passed. When no parameter is passed to the print_me method, the console output will only provide the color of the Car instance. When an argument is passed to this method (regardless of the value), we have a different behavior of this method, which is providing both the color and the number of seats of the Car instance. Here is the console output of this program
for reference:

This car is of color blue
This car is of color blue with seats 5
This car is of color blue with seats 5 

Method overriding

Having the same method name in a child class as in a parent class is known as method overriding. The implementation of a method in a parent class and a child class is expected to be different. When we call an overriding method on an instance of a child class, the Python interpreter looks for the method in the child class definition, which is the overridden method. The interpreter executes the child class-level method. If the interpreter does not find a method at a child instance level, it looks for it in a parent class. If we have to specifically execute a method in a parent class that is overridden in a child class using the child class instance, we can use the super() method to access the parent class-level method. This is a more popular polymorphism concept in Python as it goes hand in hand with inheritance and is one of the powerful ways of implementing inheritance.

To illustrate how to implement method overriding, we will update the inhertance1.py snippet by renaming the print_vehicle_info method name as print_me. As we know, print_me methods are already in the two child classes with different implementations. Here is the updated code with the changes highlighted:

#methodoverriding1.py
class Vehicle:
def __init__(self, color):
self.i_color = color
def print_me(self):
print(f"This is vehicle and I know my color is \
{self.i_color}")
class Car (Vehicle):
def __init__(self, color, seats):
self.i_color = color
self.i_seats = seats
def print_me(self):
print( f"Car with color {self.i_color} and no of \
seats {self.i_seats}")
class Truck (Vehicle):
def __init__(self, color, capacity):
self.i_color = color
self.i_capacity = capacity
def print_me(self):
print( f"Truck with color {self.i_color} and \
loading capacity {self.i_capacity} tons")
if __name__ == "__main__":
vehicle = Vehicle("red")
vehicle.print_me()
car = Car ("blue", 5)
car.print_me()

truck = Truck("white", 1000)
truck.print_me()

In this example, we override the print_me method in the child classes. When we create three different instances of Vehicle, Car, and Truck classes and execute the same method, we get different behavior. Here is the console output as a reference:

This is vehicle and I know my color is red
Car with color blue and no of seats 5
Truck with color white and loading capacity 1000 tons

Method overriding has many practical applications in real-world problems—for example, we can  inherit the built-in list class and can override its methods to add our functionality. Introducing a custom sorting approach is an example of method overriding for a list object.

In the next post we will discuss about Abstraction.


Share:

0 comments:

Post a Comment