OOP and design · Topic 10 of 12
Liskov substitution
Definition​
The Liskov substitution principle says a child class must work anywhere its parent is expected, without surprising the caller. If code that works with the parent breaks when it gets the child, the hierarchy is wrong.
Example code​
A Square that breaks code written for Rectangle, and a fix
class Rectangle {
protected int width, height;
void setWidth(int w) { width = w; }
void setHeight(int h) { height = h; }
int area() { return width * height; }
}
class BadSquare extends Rectangle { // a square keeps both sides equal...
@Override void setWidth(int w) { width = w; height = w; }
@Override void setHeight(int h) { width = h; height = h; }
}
interface Shape { int area(); } // the fix: no false "is-a"
record Rect(int width, int height) implements Shape { public int area() { return width * height; } }
record Sq(int side) implements Shape { public int area() { return side * side; } }
class Demo {
public static void main(String[] args) {
Rectangle r = new BadSquare();
r.setWidth(4);
r.setHeight(5);
System.out.println("Expected 20, got " + r.area()); // surprise: the caller's assumption broke
System.out.println(new Rect(4, 5).area());
System.out.println(new Sq(4).area());
}
}
// Output:
// Expected 20, got 25
// 20
// 16
Finished this page? Track your progress (saved only in your browser).