Skip to main content

Keep the Promise

The Liskov Substitution Principle says: anywhere the code expects a protocol, every implementation of that protocol must work correctly. An implementation that technically fits but behaves badly — raises, does nothing, lies — breaks every function that trusted the protocol.

A protocol is a promise. fly() promises flying. A class that implements fly() by raising an exception has signed a contract it cannot keep.


A Substitute That Breaks the Deal

The Bird protocol promises fly(). Sparrows deliver. Penguins are birds too — so it feels natural to implement the protocol... with a raise, because penguins cannot fly.

Now air_show, which works for every honest bird, crashes on a penguin. The bug is not in air_show — it is in the substitute that broke the promise.

The penguin that crashes the show

air_show trusts the protocol and calls fly() on every bird. The sparrow performs; the penguin raises an exception and takes the whole show down (the try/except only softens the landing to show the message).

Prompt
Write a Python program showing a Liskov Substitution violation: a Bird protocol with a fly method, a Sparrow that flies, and a Penguin whose fly raises an exception because penguins cannot fly. An air_show function calls fly on every bird; catch the exception to show the crash message when the penguin performs.
Output: complete Python program

Separate the Promises

The fix: promise only what is true. Split the fat promise into Flyer and Swimmer. The sparrow implements Flyer, the penguin implements Swimmer — and no class signs a contract it cannot keep.

The best part is who catches the mistake now: a type checker (e.g. mypy) reports air_show([Penguin()]) before the code ever runs, because a penguin has no fly() method — plain python3 would fail only when fly() is called.

Every class keeps its promise

air_show accepts Flyer, pool_show accepts Swimmer. Each animal appears only where its promise holds — substitution is safe by construction.

Prompt
Fix the Liskov violation in Python by splitting the promises: a Flyer protocol with fly and a Swimmer protocol with swim. Sparrow implements Flyer, Penguin implements Swimmer. Write air_show for flyers and pool_show for swimmers and run both, so every class only appears where its promise holds.
Output: complete Python program
Every class keeps its promise

Any Flyer can join

The payoff of honest protocols: a new Eagle joins the air show with no risk — anything that implements Flyer truly flies, so air_show never needs to doubt its input.

Prompt
Extend the Python Flyer protocol example with a new Eagle class and run an air show with several flyers, showing that any honest Flyer implementation can substitute safely.
Output: complete Python program