7 min read
Polymorphism
One instruction, many forms
The word polymorphism means "many forms". In programming it describes a small but powerful idea: the same instruction can do the right thing for different kinds of object. You already saw a hint of it with overriding, where a child class gives its own version of a parent's method. Polymorphism is what that lets you do next: call one method name across a mixed pile of objects and let each object answer in its own way.
The pay-off is code that does not have to ask "what exactly are you?" before acting. It just asks for the behaviour and trusts each object to supply it.
Different shapes, one method name
Suppose you have several shapes and you want the area of each. Give every shape class a method called area, but let each compute it correctly for its own kind.
import math
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
class Triangle:
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
Three unrelated formulas, but one shared method name. That shared name is the whole trick.
Code that does not care which shape it holds
Because every shape answers to area, a single loop can handle a mixed list of them. The loop never checks the type; it just calls the method and lets each object respond.
shapes = [Rectangle(3, 4), Circle(5), Triangle(6, 2)]
for shape in shapes:
print(round(shape.area(), 2))
# 12
# 78.54
# 6.0
If tomorrow you add a Square class with its own area, this loop keeps working untouched. That is the real gift of polymorphism: the code that uses the objects does not grow or change when you add new kinds. You write the loop once, and every well-behaved shape fits into it.
Tip
Python does not require the shapes to share a parent for this to work. It simply calls area and expects an answer, an approach often called duck typing: if it responds to area like a shape, it is treated as a shape. The agreement is the method name, not the family tree.
You have seen it already
Polymorphism is not only something you build; Python leans on it everywhere. The len function gives the number of characters in a string, the number of items in a list, and the number of keys in a dictionary. One name, and each type responds sensibly for what it is. The + sign adds two numbers but joins two strings end to end. Each time, the same instruction takes a form suited to the object it meets, which is exactly the pattern your shapes follow.
Prefer to see it explained? Here is the recorded Code for Albania lecture on this topic.
Try this now
Add a Square class with its own area method to the three shapes above, then drop a Square into the shapes list and run the same loop unchanged. Confirm it prints four areas without you touching the loop. That is polymorphism paying off: new kind, same code.
Check yourself
- In your own words, what does polymorphism let a single loop do that it otherwise could not, and why does that matter when you later add a new kind of object?
- The three shape classes are not related by inheritance, yet the loop over them works. What is the one thing they must have in common for that to happen?
- Give an everyday example from Python itself, outside the shapes, where the same instruction behaves differently depending on the kind of object it is given.
Where this lesson comes from
Built from
- Data Structures and Algorithms
alphaPlan courses are built from taught programmes rather than invented for the web. Where a claim rests on an outside standard or a reported case, it is named above so you can check it rather than take our word for it.
This course was developed by alphaPlan Center from programs delivered in partnership with the American Corners network.
Found something unclear, outdated or improvable? Suggest an improvement