Introduction
Polymorphism comes from two Greek words. Poly means many. Morphism means forms. Together, polymorphism means one method or function can take many forms and behave differently depending on the object or data type it is working with.
In Python, polymorphism is a key concept in object oriented programming. It allows different classes to have methods with the same name, while each class defines its own behavior. Because of this, a function can work with objects from different classes without needing to know their exact class type. The function only cares that the required method exists.
Key Concept: Polymorphism allows you to write flexible, reusable code where the same interface (method name) can be used for different underlying forms (data types or class types).
Real-World Analogy:
- A person can be a student in school, an employee at work, and a customer in a store - same person, different behaviors in different contexts.
- The
+operator: adds numbers (5 + 3 = 8), concatenates strings ("Hello" + "World" = "HelloWorld"), merges lists ([1,2] + [3,4] = [1,2,3,4])
Types of Polymorphism in Python
- Compile-Time Polymorphism (Method Overloading)
- Run-Time Polymorphism (Method Overriding)
- Polymorphism in class methods
- Polymorphism with functions and objects
This is often called method overloading. Python does not support traditional method overloading, but similar behavior can be achieved using default arguments or flexible parameters such as *args and **kwargs. This allows a method to handle different numbers or types of inputs.
This is also known as method overriding. It occurs when a child class provides its own implementation of a method that already exists in its parent class. The method that runs is determined at runtime based on the object type.
Different classes can define methods with the same name and interface. When these methods are called on objects of different classes, each object responds according to its own implementation.
A single function can accept objects of different classes, as long as those objects implement the expected methods or behavior. This is often described as duck typing in Python.
Polymorphism with functions and objects
Polymorphism in Python can be a bit of a mouthful, but it's a fancy way of saying that things can act in different ways depending on their type. Imagine you have a toolbox with different tools. A hammer acts differently than a screwdriver, even though they're both tools. That's kind of like polymorphism!
Here's how it works in Python with an example:
Animal Sounds:
- Let's say we have different animal classes: Dog, Cat, and Cow.
- Each animal class has a method called
make_sound()that makes the animal's sound. - But, how each animal makes a sound is different!
class Dog:
def make_sound(self):
print("Woof!")
class Cat:
def make_sound(self):
print("Meow!")
class Cow:
def make_sound(self):
print("Moo!")
One Function for All:
Now, imagine we have a function called play_sound() that takes an animal as an argument.
Even though each animal has its own make_sound() method, we can use the same play_sound() function for all of them!
# One function to play the sound of any animal
def play_sound(animal): # the argument can be any choose name we want
animal.make_sound() # We don't care what kind of animal it is, just call its make_sound() method# Instantiate the objects
my_dog = Dog()
my_cat = Cat()
my_cow = Cow()
# All the objects have a make_sound() method, so we can pass any of them to the play_sound() function
play_sound(my_dog) # Output: Woof!
play_sound(my_cat) # Output: Meow!
play_sound(my_cow) # Output: Moo!
The Magic of Polymorphism:
- In this example,
play_sound()is polymorphic because it can work with different animal objects, even though they have differentmake_sound()methods. - Python automatically figures out which
make_sound()method to call based on the type of animal object passed in. Benefits of Polymorphism: - Makes code more flexible and reusable.
- Easier to add new animal classes without changing the play_sound() function.
- Keeps code cleaner and more organized.
So, polymorphism allows you to write code that can handle different types of objects in a similar way, making your Python programs more adaptable and efficient!
Another Example:
Products and Discounts:
- Let's create classes for different types of products: Book, Shirt, and Movie.
- Each product class has a
calculate_discount()method that applies a specific discount based on the product type.
One Function for Discounts:
- Now, we have a function called
apply_discount()that takes adiscount_infoobject as an argument. - Even though each product has its own discount logic, we can use the same
apply_discount()function for all of them!
def apply_discount(discount_info):
# Polymorphism in action! Python calls the product's specific calculate_discount() method
discount_info.calculate_discount()
# Assign the result to a variable
discounted_price = discount_info.calculate_discount()
# Print the result
print(f"{discount_info.name} after discount: ${discounted_price:.2f}")
Polymorphism at Work:
- In this example, apply_discount() is polymorphic because it can work with different product objects, even though they have different calculate_discount() methods.
- Python automatically determines the correct method to call based on the product type passed in.
This demonstrates how polymorphism allows you to create reusable code that can handle various product types with their respective discount calculations.