🐍 Python Q26 / 183

What is polymorphism in Python?

AI-Powered Answer ✓ Answered

Polymorphism, a core concept in Object-Oriented Programming (OOP), means 'many forms'. In Python, it allows objects of different classes to be treated as objects of a common type, enabling a single interface to represent different underlying forms. Python's dynamic typing naturally facilitates polymorphism.

What is Polymorphism?

Polymorphism literally means having 'many forms'. In the context of programming, it refers to the ability of an object to take on many forms. It allows functions, methods, or operators to work with objects of different types in a uniform way.

Python, being an object-oriented and dynamically typed language, inherently supports polymorphism. This means you don't always need explicit inheritance hierarchies to achieve polymorphic behavior; duck typing plays a significant role.

Types of Polymorphism in Python

1. Method Overriding (Inheritance Polymorphism)

Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. The method in the subclass 'overrides' the method in the superclass, and when called on an object of the subclass, the subclass's version is executed.

python
class Animal:
    def speak(self):
        return "Generic animal sound"

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

def make_animal_speak(animal):
    return animal.speak()

dog = Dog()
cat = Cat()
animal = Animal()

# Polymorphic behavior: The same function call results in different output
# based on the object's type.
print(make_animal_speak(dog))
print(make_animal_speak(cat))
print(make_animal_speak(animal))

2. Method Overloading (Achieved through Flexible Arguments)

Traditional method overloading (where multiple methods with the same name but different parameter types or numbers exist) is not directly supported in Python in the same way as in statically typed languages like Java or C++. Python's dynamic typing and features like default arguments, or *args and **kwargs, allow achieving similar flexible behavior with a single method name.

python
class Calculator:
    def add(self, a, b=None, c=None):
        if b is not None and c is not None:
            return a + b + c
        elif b is not None:
            return a + b
        else:
            return a

calc = Calculator()
print(calc.add(5))       # One argument
print(calc.add(5, 10))   # Two arguments
print(calc.add(5, 10, 15)) # Three arguments

3. Duck Typing (Interface Polymorphism)

Duck typing is a key concept in Python polymorphism. It states: 'If it walks like a duck and quacks like a duck, then it must be a duck.' In programming terms, if an object has the necessary methods or attributes to perform an operation, then it can be used for that operation, regardless of its actual class or inheritance hierarchy.

This means that polymorphism in Python is often about behavioral compatibility rather than strict type compatibility. Any object that defines a particular method can be treated polymorphically by a function expecting that method.

python
class Duck:
    def make_sound(self):
        return "Quack!"

class Person:
    def make_sound(self):
        return "Hello!"

class Car:
    def drive(self):
        return "Vroom!"

def get_sound(entity):
    if hasattr(entity, 'make_sound'): # Check if the object has the 'make_sound' method
        return entity.make_sound()
    else:
        return "This entity does not make a sound."

duck = Duck()
person = Person()
car = Car()

print(get_sound(duck))
print(get_sound(person))
print(get_sound(car))

Benefits of Polymorphism

  • Code Reusability: Write generic code that can work with different types of objects, as long as they adhere to a common interface (e.g., have the same method names).
  • Flexibility and Extensibility: Easily add new classes or types without modifying existing code, as long as the new types implement the expected polymorphic interface.
  • Readability and Maintainability: Leads to cleaner, more organized, and easier-to-understand code by abstracting common behaviors.