Polymorphism in Python
In Python, polymorphism is a concept where objects of different types can be accessed and used through a single interface. It allows different objects to respond to the same method or function in different ways depending on their implementation. Polymorphism in Python can be achieved through method overloading, method overriding, or through the use of abstract classes and interfaces.
Polymorphism
Polymorphism is a concept in programming where different objects can be accessed and used through a single interface, allowing them to respond to the same function or method in different ways depending on their implementation.
Method overloading is a technique where multiple methods can have the same name but with different parameters. Python does not support method overloading natively, but it can be achieved using default arguments, variable arguments, or using libraries like NumPy.
Method overriding is a technique where a subclass provides its own implementation of a method that is already defined in its parent class. This allows the subclass to provide a specialized implementation of the method while maintaining the same method signature as the parent class.
Abstract classes and interfaces are used to define a blueprint for other classes to follow. Abstract classes cannot be instantiated and must be subclassed to be used. Interfaces provide a way to define a set of methods that a class must implement to be considered as an implementation of the interface.
Polymorphism is a powerful feature of object-oriented programming that allows for more flexible and modular code.
In Python, we can demonstrate polymorphism using both method overloading and method overriding. Here are examples of both:
Method Overloading
As mentioned earlier, Python does not support method overloading natively. However, we can achieve the same effect using default arguments, variable arguments, or using libraries like NumPy.
Example 1: Using Default Arguments
class MyClass:
def sum(self, a=None, b=None, c=None):
if a is not None and b is not None and c is not None:
return a + b + c
elif a is not None and b is not None:
return a + b
else:
return a
obj = MyClass()
print(obj.sum(10, 20, 30)) # Output: 60
print(obj.sum(10, 20)) # Output: 30
print(obj.sum(10)) # Output: 10
In this example, we define a class MyClass with a method sum() that takes default arguments a=None, b=None, and c=None. The sum() method checks which arguments are not None and performs the appropriate addition operation. Here, we can call the sum() method with 3, 2, or 1 arguments and get different outputs.
Example 2: Using Variable Arguments
class MyClass:
def sum(self, *args):
total = 0
for i in args:
total += i
return total
obj = MyClass()
print(obj.sum(10, 20, 30)) # Output: 60
print(obj.sum(10, 20)) # Output: 30
print(obj.sum(10)) # Output: 10
In this example, we define a class MyClass with a method sum() that takes variable arguments *args. The sum() method iterates over all the arguments passed and adds them to a total variable, which is then returned. Here, we can call the sum() method with any number of arguments and get the sum of all the arguments.
Method Overriding
In Python, we can achieve method overriding by defining a method with the same name in the subclass as in the parent class. The method in the subclass will override the method in the parent class with the same name and signature.
Example code:
class Animal:
def sound(self):
print("This animal makes a sound.")
class Dog(Animal):
def sound(self):
print("The dog barks.")
class Cat(Animal):
def sound(self):
print("The cat meows.")
obj_animal = Animal()
obj_dog = Dog()
obj_cat = Cat()
obj_animal.sound() # Output: This animal makes a sound.
obj_dog.sound() # Output: The dog barks.
obj_cat.sound() # Output: The cat meows.
In this example, we can define a parent class Animal with a method sound() that simply prints a message that the animal makes a sound. We can then define two subclasses Dog and Cat that inherit from the Animal class and override the sound() method to print a different message.
When we create objects of the Animal, Dog, and Cat classes, we can call the sound() method on each object. Although we are calling the same method on each object, we get a different output depending on the type of object. This is because each subclass has its own implementation of the sound() method.
This is an example of how we can use method overriding to achieve polymorphism in Python.
Polymorphism in Python means that we can use the same method or function in different ways, depending on the object that is using it. This allows us to write flexible and reusable code.
Polymorphism in Class Methods in Python
Example
class Shape:
def area(self):
pass
class Rectangle(Shape):
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
rect = Rectangle(5, 10)
print(rect.area()) # Output: 50
circle = Circle(7)
print(circle.area()) # Output: 153.86
In this example, we define a parent class Shape with a method area() that is left empty (using the pass statement). We then define two subclasses Rectangle and Circle that inherit from the Shape class and implement their own area() method to calculate the area of the respective shapes.
When we create objects of the Rectangle and Circle classes, we can call the area() method on each object. Although we are calling the same method on each object, we get a different output depending on the type of object. This is because each subclass has its own implementation of the area() method.
This is an example of how we can use polymorphism in class methods to write more flexible and reusable code, where the same method name can be used for different types of objects with different implementations.
Example of function polymorphism in Python:
def add(x, y):
return x + y
print(add(1, 2)) # Output: 3
print(add("Hello", "World")) # Output: HelloWorld
print(add([1, 2, 3], [4, 5, 6]))
# Output: [1, 2, 3, 4, 5, 6]
In this example, we define a function add() that takes two arguments and returns their sum. We then call the function with different types of arguments - integers, strings, and lists.
Although we are calling the same function with different types of arguments, we get a different output depending on the type of argument. This is because Python supports polymorphism in functions, where the same function can be used with different types of arguments, and the behavior of the function can change based on the type of argument.
This is an example of how we can use function polymorphism to write more flexible and reusable code, where the same function name can be used for different types of arguments with different implementations.
Polymorphism in Python using inheritance and method overriding
Example
class Animal:
def sound(self):
print("This animal makes a sound.")
class Dog(Animal):
def sound(self):
print("The dog barks.")
class Cat(Animal):
def sound(self):
print("The cat meows.")
animal = Animal()
animal.sound() # Output: This animal makes a sound.
dog = Dog()
dog.sound() # Output: The dog barks.
cat = Cat()
cat.sound() # Output: The cat meows.
Output:
This animal makes a sound.
The dog barks.
The cat meows.
When we call the sound() method on the animal object of the Animal class, it prints the message "This animal makes a sound.".
When we call the sound() method on the dog object of the Dog class, it overrides the implementation of the sound() method in the parent Animal class and prints the message "The dog barks.".
When we call the sound() method on the cat object of the Cat class, it overrides the implementation of the sound() method in the parent Animal class and prints the message "The cat meows.".
Polymorphism is a powerful programming concept that allows the same function or method name to be used for different types of objects with different implementations. This provides flexibility and reusability in the code and helps to reduce code duplication.
Polymorphism can be achieved in various ways in Python, such as using method overloading, method overriding, inheritance, and function overloading. By using these techniques, we can write more flexible and modular code that is easier to maintain and extend.
Polymorphism is a fundamental concept in object-oriented programming, and mastering it is essential for writing effective and efficient code.