Class Polymorphism
- Class polymorphism means that objects of different classes can be used interchangeably, as long as they implement a common interface (i.e., same method names or behavior). This is usually achieved through inheritance and method overriding.
- This allows you to write general-purpose code that works with a variety of classes, increasing flexibility and reducing redundancy.
Polymorphism via Inheritance (Method Overriding)
- When a subclass defines a method with the same name as one in its parent class, it overrides the method. You can then use these classes polymorphically.
- Even though all objects are treated as Animal, the actual method executed is from the actual
class (Dog, Cat, etc.). - This is classic class-based polymorphism.
Using Polymorphic Functions with Different Classes
- A function can accept different types of objects as long as they implement the required methods — this is polymorphism in action.
- Even though Duck and Person are unrelated classes, the function sound_test() works because both implement make_sound().
- This is also called interface-based polymorphism (or duck typing in Python).
Polymorphism with Abstract Base Classes (ABC)
- In more formal designs, polymorphism is enforced using abstract base classes, which require subclasses to implement certain methods.
- Shape defines a common interface (area()).
- Subclasses implement their own logic.
- You can treat all of them as Shape objects: a powerful example of class polymorphism.
Duck Typing
- “If it walks like a duck and quacks like a duck, it's a duck.”
- Duck typing is a type of dynamic (runtime) polymorphism in Python where an object’s suitability is determined by the presence of certain methods or properties, rather than the actual type of the object.
- In other words, Python cares more about what an object can do than what it is.
Example: Duck Typing
- Duck and Person are unrelated classes.
- The make_it_quack() function works with both because they have a quack() method.
Duck Typing vs Inheritance (Inheritance Approach)
- Inheritance-based polymorphism requires a common base class.
-
No base class needed: as long as speak() exists, the function works.
Example with File-like Objects
- This is a real-world use of duck typing in Python's built-in libraries.
- Here, read_data() doesn’t care whether it’s dealing with an actual file or a string buffer — as long as the object has a read() method, it works.
Caution with Duck Typing
- Since Python is dynamically typed, duck typing can lead to runtime errors if the expected method or attribute is missing.
- To avoid this, one option is to use hasattr() to check:
- Another option is to use try/catch to handel errors: