mathspp
  • Blog
    • Pydon'ts
    • Problems
    • TIL
    • Twitter threads
  • Books
  • Talks
  • Trainings
    • Advanced iteration
    • Python for scripting and automation
    • Rust for Python developers
  • Courses
  • About
Link blog

What is an example of the Liskov Substitution Principle? - Stack Overflow

on 27-01-2025 21:40

When working with typed Python code I get mypy complaining about the Liskov Substitution Principle quite frequently. I end up rereading an explanation of it and it looks absolutely obvious to me. So, I don't get how/why I keep messing it up.

A cat is an animal. Therefore, if you have the class Animal and want to create a class Cat, you have to make sure that wherever you can use a class Animal, you can replace that with Cat and the code should still work. For example, here's an easy way to break the LSP:

class Animal:
    def eat(self, food: Animal) -> None:
        pass

class Fish(Animal):
    ...

class Cat(Animal):
    def eat(self, food: Fish) -> None:  # <--
        pass

This breaks the LSP because the current definition of Animal.eat lets me write something like Animal().eat(Cat()), and a cat is an animal, so wherever I can use a generic animal I should also be able to write a cat. However, Cat().eat(Cat()) doesn't work because Cat.eat expects fish. Therefore, I conclude that there's something fishy with Animal.eat / Cat.eat.

Previous link Next link

You didn't ask, but let me tell you I learned a lot of maths over at KhanAcademy.

mathspp
  • Blog
    • Pydon'ts
    • Problems
    • TIL
    • Twitter threads
  • Books
  • Talks
  • Trainings
    • Advanced iteration
    • Python for scripting and automation
    • Rust for Python developers
  • Courses
  • About