What is Polymorphism?
Polymorphism is a key idea in Object-Oriented Programming (OOP). The word “polymorphism” comes from Greek. “Poly” means “many.” “Morph” means “forms.” So, polymorphism means “many forms.”
In Python, polymorphism allows one thing to do different actions. This could be a function, a method, or an operator. The action it takes depends on the type of data it works with. This means you can call the same method on different objects. Each object will then respond in its own special way.
3 Ways to Use Polymorphism in Python
You can use polymorphism in Python in a few ways:
- With Built-in Functions: Python’s own functions often use polymorphism.
- With Class Methods: Different classes can have methods that share the same name.
- With Inheritance (Method Overriding): Child classes can change methods they get from their parent classes.
In this course, you will learn the fundamentals of Python: from basic syntax to mastering data structures, loops, and functions. You will also explore OOP concepts and objects to build robust programs.
Let’s look at each way.
1. Polymorphism with Built-in Functions
Many built-in Python functions work in different ways. Their action changes based on the type of data you give them. The len()
function is a good example.
- When you use
len()
on a string, it counts the characters. - When you use
len()
on a list, it counts the items. - When you use
len()
on a dictionary, it counts the keys.
Here’s how len()
works:
# Use len() with a string
my_string = "hello"
print(len(my_string))
# Use len() with a list
my_list = [1, 2, 3, 4]
print(len(my_list))
# Use len() with a dictionary
my_dict = {"a": 1, "b": 2}
print(len(my_dict))
This code outputs:
5
4
2
The len()
function acts differently for each data type. This shows polymorphism. You use one function name. But it behaves in “many forms” based on what you give it. This makes len()
very flexible. You do not need different functions to count items in strings, lists, or dictionaries.
2. Polymorphism with Class Methods
You can define methods with the same name in different classes. These classes do not need to be related through inheritance. You can still call the same method on objects created from these different classes.
Think about these two classes: Dog
and Cat
. Both have a sound()
method.
class Dog:
def sound(self):
print("Woof!")
class Cat:
def sound(self):
print("Meow!")
# Make objects (instances) from these classes
my_dog = Dog()
my_cat = Cat()
# Call the same method on different objects
my_dog.sound()
my_cat.sound()
This code outputs:
Woof!
Meow!
You call sound()
on both my_dog
and my_cat
. Each object runs its own version of sound()
. This is polymorphism in action. Each object knows how to make its own sound when sound()
is called.
You can also put these objects into a list. Then, you can loop through the list. Call the same method on each object:
class Dog:
def sound(self):
print("Woof!")
class Cat:
def sound(self):
print("Meow!")
# Make a list of different animal objects
animals = [Dog(), Cat()]
# Loop through the list
# Call the 'sound' method on each animal
for animal in animals:
animal.sound()
This code outputs:
Woof!
Meow!
The animal.sound()
call works for both Dog
and Cat
objects. This is true even if they are different types. The code stays clean. You do not need separate if/else
checks for each animal type. This makes your code simpler. It also makes it easier to expand. If you add a new Cow
class with a sound()
method, this loop would still work without any changes.
3. Polymorphism with Inheritance (Method Overriding)
Polymorphism often goes with inheritance. Inheritance is when a child class gets features from a parent class. When a child class gets a method from a parent, it can redefine that method. This is called method overriding.
The child class creates its own specific way of doing the inherited method. It essentially replaces the parent’s method with its own version.
Here is an example. We have a Vehicle
parent class. Then we have Car
and Motorcycle
child classes:
class Vehicle:
def describe(self):
print("This is a generic vehicle.")
class Car(Vehicle): # Car gets features from Vehicle
def describe(self): # Car redefines the describe method
print("This is a sporty car.")
class Motorcycle(Vehicle): # Motorcycle gets features from Vehicle
def describe(self): # Motorcycle redefines the describe method
print("This is a fast motorcycle.")
# Make objects from each class
vehicle = Vehicle()
car = Car()
motorcycle = Motorcycle()
# Call the describe method on different objects
vehicle.describe()
car.describe()
motorcycle.describe()
This code outputs:
This is a generic vehicle.
This is a sporty car.
This is a fast motorcycle.
Each object’s describe()
method acts differently. The Car
and Motorcycle
classes override the describe()
method from Vehicle
. When you call describe()
on a Car
object, you get the car’s description. The same happens for the Motorcycle
. Python knows which describe()
method to call. It picks the right one based on the object’s actual type.
You can also use one function that takes a Vehicle
object. This function will then work with any of its child classes. It does not need special code for each one:
class Vehicle:
def describe(self):
print("This is a generic vehicle.")
class Car(Vehicle):
def describe(self):
print("This is a sporty car.")
class Motorcycle(Vehicle):
def describe(self):
print("This is a fast motorcycle.")
# A function that takes any object with a 'describe' method
def show_description(item):
item.describe()
# Make objects
car = Car()
motorcycle = Motorcycle()
generic_vehicle = Vehicle()
# Call the function with different objects
show_description(car)
show_description(motorcycle)
show_description(generic_vehicle)
This code outputs:
This is a sporty car.
This is a fast motorcycle.
This is a generic vehicle.
The show_description()
function works with Car
, Motorcycle
, and Vehicle
objects. It does not need to know the specific type of vehicle. It just calls the describe()
method. Python then figures out the correct version to use.
This makes your code more flexible. It also helps you reuse code. If you add a new type of Vehicle
, like a Truck
, you only need to give it a describe()
method. The show_description()
function will then work with it automatically.
Benefits of Polymorphism
Polymorphism offers several good points in your Python code:
- Flexible Code: It helps you write code that can work with different types of objects. You use one simple way to interact with many different objects.
- Reusable Code: You can write one function or method. This one piece of code can then process many different objects. This means less repeated code in your program. You write less code, and it does more work.
- Easier to Maintain: When you add new types of objects, you usually do not need to change existing code. This is true as long as the new types have the necessary methods. This makes updating and fixing your programs simpler.
- Clearer Code: It makes your code cleaner and easier to understand. You avoid writing many complex
if/else
statements to handle different object types.