14-4. Class Polymorphism

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: