Subtypes must be substitutable for their base type without breaking behavior.
# dirty — Square breaks Rectangle's contract
class Rectangle:
def set_width(self, w):
self.width = w
def set_height(self, h):
self.height = h
def area(self):
return self.width * self.height
class Square(Rectangle):
def set_width(self, w):
self.width = w
self.height = w # breaks LSP!
def set_height(self, h):
self.width = h
self.height = hRefactor using factory functions so create_rectangle and create_square are independent — no inheritance. Both expose an area callable.
solve('square', 5) → 25 (side²)solve('rect', 4, 6) → 24 (width × height)
Sample tests