liveBook · Manning

Liskov Substitution Principle

As explained in Practices of the Python Pro

The Liskov substitution principle states that objects of a subtype must be replaceable for objects of its supertype without impairing program correctness.

Requires every subclass instance to replace its superclass instance without making the program incorrect. The replacement should preserve the superclass interface and basic outcomes, even when implementation details differ. section 8.2.2

When specialization breaks substitution

A Snail subclass of Slug adds a required shell_size argument. Code that creates a Slug can no longer replace it with a Snail without changing its call. A snail has a shell, so composition may fit better than inheritance. section 8.2.2

Check a subclass by asking:

  • Does it preserve inherited method signatures and behavior? section 8.2.2
  • Does it fulfill the same role as every other class in the hierarchy? section 8.2.2
  • Does it avoid unused behavior, no-op overrides, or exceptions that invalidate superclass expectations? section 8.2.3
Listing 8.1. A subclass that breaks substitutability
class Slug:
    def __init__(self, name):
        self.name = name

    def crawl(self):
        print('slime trail!')

class Snail(Slug):                         #1
    def __init__(self, name, shell_size):  #2
        super().__init__(name)
        self.name = name
        self.shell_size = shell_size

def race(gastropod_one, gastropod_two):
    gastropod_one.crawl()
    gastropod_two.crawl()

race(Slug('Geoffrey'), Slug('Ramona'))     #3
race(Snail('Geoffrey'), Snail('Ramona'))   #4

Inspect the Slug and Snail example to see how a changed constructor prevents direct substitution. section 8.2.2

How Practices of the Python Pro covers it

How deep it goes
Defines substitution, tests signatures and exceptions, and contrasts inheritance with composition through short Python examples.
Examples
Uses Slug and Snail, Bird and Penguin, and a Bicycle model exercise.
What it assumes
Assumes basic classes and inheritance while teaching substitutability through introductory Python examples.
What you can do after
Diagnose inheritance designs by checking replacement behavior and choosing composition when specialization cannot preserve expectations.
How it connects
Connects inheritance, subclasses, interfaces, composition, and the is-a relationship.

Also explained in

Compare how 5 books explain Liskov Substitution Principle →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Practices of the Python Pro. The section links point to the parts of the book it draws on.