Latticework

Command Palette

Search for a command to run...

Object-Oriented Programming

Polymorphism

18 min

Explanation

Polymorphism means calling the SAME method name on different types and having each one do its own type-appropriate thing — you already saw the mechanism in the last module (Square inheriting Rectangle.area), but the real power shows up when you have a MIX of types and treat them uniformly:

class Shape:
    def area(self):
        raise NotImplementedError

class Rectangle(Shape):
    def __init__(self, w, h):
        self.w, self.h = w, h
    def area(self):
        return self.w * self.h

class Circle(Shape):
    def __init__(self, r):
        self.r = r
    def area(self):
        import math
        return math.pi * self.r ** 2
Try it

This loop never checks 'if it's a Rectangle, do X; if it's a Circle, do Y' -- calling .area() just works for every shape, because each class knows how to compute its OWN area. That's polymorphism doing the dispatching for you.

Loading editor…
Explanation

Sometimes you need to know an object's ACTUAL type at runtime — not to change behavior (that's what polymorphism already handles automatically via .area()), but for things like logging or display. type(obj).__name__ gives you the class name as a string:

for s in shapes:
    print(f"{type(s).__name__}: {s.area():.2f}")
# Rectangle: 6.00
# Circle: 3.14
# Rectangle: 16.00

A common beginner mistake is reaching for if isinstance(s, Rectangle): ... elif isinstance(s, Circle): ... to handle each type differently — that defeats the entire point of polymorphism. If you find yourself writing that kind of type-checking chain, it's usually a sign the logic belongs inside each class's own method instead.

Exercise

Given `Shape`, `Rectangle`, and `Circle` below (all with a working `area()`), write `total_area(shapes)`: sum every shape's `area()` — calling `.area()` should work identically regardless of each shape's actual type. Round the result to 4 decimals.

Exercise

Write `describe_shapes(shapes)`, returning a list of strings like `"Rectangle: area=12"` for each shape — use `type(s).__name__` to get each shape's actual class name, and round each area to 2 decimals.

Quiz

What is 'polymorphism' in OOP?

Checkpoint

You can write code that treats a mix of related object types uniformly through their shared method interface, letting each object's own implementation handle the type-specific behavior.