Lesson 4 · OKSTEM College · Associate of Science in Computer Science
Polymorphism & Duck Typing
Polymorphism means "many forms" — the same interface works across different types. Python uses duck typing: if an object has the right methods, it works, regardless of its class.
"If it walks like a duck and quacks like a duck, it is a duck." — Python cares about behaviour, not declared type.
classDog:
defspeak(self): return"Woof!"classCat:
defspeak(self): return"Meow!"classRobot:
defspeak(self): return"Beep boop."defmake_noise(thing): # accepts ANY object with .speak()print(thing.speak())
for obj in [Dog(), Cat(), Robot()]:
make_noise(obj)
# Woof! Meow! Beep boop.
Method Overriding with super()
Overriding replaces a parent method. Calling super().method() inside the override lets you extend rather than fully replace the behaviour.
Define a Shape base class with area() and describe().
Subclass Circle and Rect, each overriding area().
Write a render_all(shapes) function that loops and calls describe() on each — no if/isinstance needed.
import math
classShape:
defarea(self): return0defdescribe(self):
print(f"{self.__class__.__name__}: area = {self.area():.2f}")
classCircle(Shape):
def__init__(self, r): self.r = r
defarea(self): return math.pi * self.r ** 2classRect(Shape):
def__init__(self, w, h): self.w=w; self.h=h
defarea(self): returnself.w * self.h
defrender_all(shapes):
for s in shapes:
s.describe()
render_all([Circle(5), Rect(4, 6), Circle(2)])
# Circle: area = 78.54# Rect: area = 24.00# Circle: area = 12.57
Practice Problems
1. Why is using isinstance() checks in render_all() considered bad polymorphism?
It breaks the Open/Closed principle. Every time you add a new Shape
subclass, you must update render_all(). With true polymorphism,
each class handles its own behaviour — render_all never changes.
2. Add a Triangle class and verify render_all() works without changes.