Before you start
This is the last lesson of the OOP foundations module. It puts a name on something you've already been doing, and gives you a bigger toolkit for the rest of the course.
What you already know without knowing it
Polymorphism is not a new idea. You've been using it:
- Lesson 3. A list of Vehicle subclasses, each with its
own
describe(). The loopfor v in fleet: print(v.describe())doesn't care which subclass eachvis. That's polymorphism. - Lesson 4. A list of notification channels. Same thing.
The formal word is polymorphism. Greek roots: poly (many)
- morph (shape). Many shapes, one way to use them.
Two ways to spell the rule
Python gives you two choices:
Duck typing — the loose default. If it walks like a duck. No declaration needed. Just call the methods and hope.
Abstract base class (ABC) — the formal contract. Says "every child class MUST have these methods". If a child is missing one, Python refuses to build it.
Real production Python uses both. Rough guide:
- Two or three methods, all your own code → duck typing
- Public interface, many child classes possible → ABC
For interviews, using ABC shows design maturity — you're naming the rule instead of leaving it implicit. Interviewers notice.
Why "abstract" is a library, not a keyword
In Java or C#, abstract is built into the language. In
Python, it's a library — abc.ABC + @abstractmethod. The
effect is the same:
- You can't build the parent class directly.
- Child classes that don't have all the required methods ALSO can't be built.
- Child classes that have every required method can be built freely.
This is Python's style: don't invent language features when a library will do.
The pattern preview
Almost every design pattern in module 3 uses this shape. Strategy? A base with abstract methods and concrete strategies. Observer? Same. Command? Same. State? Same.
Get comfortable with the ABC-plus-child-classes shape today. You'll see it everywhere from now on.
Payment methods as the running example
Payments are the classic example for a reason: every real
e-commerce system has 5-10 payment types, and every one has
the same three-verb shape (charge, refund, sometimes
pre-authorize). The alternative — a giant if method == "credit_card": ... elif method == "upi": ... — is exactly
what the open-closed principle (next module) tells you to
avoid.
Build this correctly today and the design pattern module will feel like a natural next step.