Python OOP
Python Polymorphism
Polymorphism means the same method name can behave differently depending on which object calls it — a core idea that keeps object-oriented code flexible.
Method Overriding
When a child class defines a method with the same name as one in its parent class, the child's version overrides the parent's version. This lets each class customise shared behaviour.
class Shape:
def area(self):
print("Area not defined")
class Rectangle(Shape):
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
print(f"Area: {self.w * self.h}")
class Circle(Shape):
def __init__(self, r):
self.r = r
def area(self):
print(f"Area: {3.14 * self.r ** 2}")
for shape in [Rectangle(4, 5), Circle(3)]:
shape.area()Area: 20
Area: 28.26Notice the loop calls shape.area() without caring whether shape is a Rectangle or a Circle — each object runs its own overridden version. This is polymorphism in action.
Duck Typing
Python does not require objects to share a common parent class to be treated the same way. If an object has the method or attribute you need, Python is happy to use it — "if it walks like a duck and quacks like a duck, it is a duck."
class Printer:
def start(self):
print("Printer is printing")
class Scanner:
def start(self):
print("Scanner is scanning")
for device in [Printer(), Scanner()]:
device.start()Duck typing is why Python functions can happily accept lists, tuples or any custom object as long as it supports the operations used, like len() or iteration.
Polymorphism also applies to built-in operators — the + operator behaves differently for numbers, strings and lists, which is a form of polymorphism you have already been using.
