Polymorphism in Python

Polymorphism is a fundamental concept in object-oriented programming (OOP). It allows objects of different classes to respond to the same method name in ways appropriate to their types. In Python, polymorphism is primarily achieved through method overriding and can be simulated through flexible argument handling.



Understanding Polymorphism

Polymorphism means "many forms." In Python, it refers to the ability to call the same method on different types of objects, each responding in its own way. This enables flexible and reusable code.

There are two main forms of polymorphism in Python:

  • Method Overriding: A child class provides its own implementation of a method inherited from the parent class.
  • Method Overloading: While Python doesn’t support traditional method overloading (multiple methods with the same name but different parameters), similar behavior can be achieved using default or variable-length arguments.

Method Overriding

Method overriding occurs when a child class redefines a method from its parent class. This allows subclasses to modify or extend the behavior of inherited methods.

Example of Method Overriding

Let’s look at an example where the Dog and Cat classes override the make_sound() method of the Animal base class.

python
class Animal:
    def make_sound(self):
        print("Animal makes a sound")

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

# Create instances
dog = Dog()
cat = Cat()

# Call overridden methods
dog.make_sound()  # Output: Woof!
cat.make_sound()  # Output: Meow!

Each subclass responds differently to the same method call, demonstrating polymorphic behavior.


Method Overloading

Python doesn’t support method overloading in the traditional sense; defining multiple methods with the same name will override the previous ones. However, you can simulate overloading using default or variable-length arguments.

Using Default Arguments

You can provide default values for parameters to allow flexible usage of a method.

python
class Greeter:
    def greet(self, name="Guest"):
        print(f"Hello, {name}!")

greeter = Greeter()
greeter.greet()         # Output: Hello, Guest!
greeter.greet("John")   # Output: Hello, John!

Using Variable-Length Arguments

Another technique is to use *args to handle different numbers of arguments:

python
class Greeter:
    def greet(self, *args):
        if not args:
            print("Hello, Guest!")
        else:
            print(f"Hello, {args[0]}!")

greeter = Greeter()
greeter.greet()         # Output: Hello, Guest!
greeter.greet("Alice")  # Output: Hello, Alice!

Polymorphism in Objects

One of the most useful features of polymorphism is that it allows you to write code that works with different types of objects in the same way — as long as they share a common method name.

For example, Dog and Cat are different classes that both define a method called make_sound(). Even though they’re different types, they behave predictably when you use them interchangeably in your code.

Example: Calling the Same Method on Different Objects

Here's a complete example demonstrating polymorphism with different objects:

python
class Animal:
    def make_sound(self):
        print("Animal makes a sound")

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

animals = [Dog(), Cat()]

for animal in animals:
    animal.make_sound()

Output:

Woof!
Meow!

Even though Dog and Cat are different types, Python correctly dispatches the make_sound() call to the appropriate method. This illustrates the power of polymorphism in simplifying code.


Summary

Polymorphism allows functions and methods to use objects of different types through a common interface. In Python, this is most commonly achieved through method overriding. Though method overloading isn’t natively supported, it can be mimicked using default arguments and *args. This makes your code more flexible, extensible, and easier to maintain.


Frequently Asked Questions

What is polymorphism in Python?

Polymorphism in Python allows different object types to respond to the same method call in their own way, enabling flexible and reusable code.


What are the types of polymorphism in Python?

Python supports method overriding through inheritance and simulates method overloading using default arguments or variable-length argument lists.


Does Python support method overloading?

Python does not support traditional method overloading, but similar behavior can be achieved using default parameter values or *args/**kwargs.


What is method overriding in Python?

Method overriding occurs when a subclass provides a specific implementation of a method already defined in its parent class.


How does polymorphism improve code flexibility?

Polymorphism lets you write code that can work with objects of different types as long as they share a common interface, making your programs more maintainable and extensible.



What's Next?

In the next section, we’ll explore how to create and use modules in Python — including importing your own files and leveraging built-in functionality from the standard library.