Class Polymorphism
Definition
Class polymorphism refers to the ability of a method to have the same name but behave differently depending on the class of the object that invokes it. In other words, the same method name can perform different tasks depending on which class’s instance it is called on.
Purpose
The primary purpose of class polymorphism is to abstract and manage different behaviors of objects while maintaining a common interface. This allows for more flexible and reusable code by interacting with objects of various classes in a uniform way.
Detailed Examples
Example 1: Animal Sounds
Consider an example with different animal classes, each implementing a make_sound method.
class Animal: def make_sound(self): raise NotImplementedError("Subclasses should implement this!") class Dog(Animal): def make_sound(self): return "Woof!" class Cat(Animal): def make_sound(self): return "Meow!" class Cow(Animal): def make_sound(self): return "Moo!" def make_animal_sound(animal): print(animal.make_sound()) # Using polymorphism animals = [Dog(), Cat(), Cow()] for animal in animals: make_animal_sound(animal)
Explanation
- Base Class (Animal): Defines a make_sound method that must be implemented by subclasses. It raises a NotImplementedError to indicate that this method should be overridden in derived classes.
- Subclasses (Dog, Cat, Cow): Each subclass overrides the make_sound method to return a specific sound.
- Function make_animal_sound: Accepts an Animal object and calls the make_sound method. Due to polymorphism, it calls the appropriate make_sound method depending on the actual class of the object (Dog, Cat, or Cow).
Example 2: Geometric Shapes
Here’s a more complex example involving geometric shapes.
class Shape: def area(self): raise NotImplementedError("Subclasses should implement this!") class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): import math return math.pi * self.radius ** 2 def display_area(shape): print(f"The area is: {shape.area()}") # Using polymorphism shapes = [Rectangle(3, 4), Circle(5)] for shape in shapes: display_area(shape)
Explanation
- Base Class (Shape): Defines an area method that should be overridden by subclasses. It raises a NotImplementedError to enforce the implementation in derived classes.
- Subclasses (Rectangle, Circle): Each provides its own implementation of the area method, specific to its shape.
- Function display_area: Can handle objects of different types (Rectangle, Circle) thanks to polymorphism, and it uses the area method specific to each shape.
Advantages of Class Polymorphism
- Flexibility: You can add new classes without modifying existing code that uses these classes. For example, adding a new Bird class would not require changes to the make_animal_sound
- Reusability: Functions or methods can be written to work with the base class and, by extension, with any derived class. This increases code reusability and reduces duplication.
- Abstraction: Code interacting with objects can be written to work with the base class interface without needing to know the details of each derived class. This allows for simpler and cleaner code.
In summary, class polymorphism in Python allows you to handle objects of different classes in a uniform manner by using methods with the same name but different implementations. This makes your code more flexible, reusable, and easier to maintain.