# Liskov Substitution and Interface Segregation — Object-Oriented Programming (OOP)

Source: https://www.skillbyai.com/en/oop/s-lsp-isp

> Keep subtypes substitutable and interfaces small.

## Honest subtypes and focused contracts

The **Liskov Substitution Principle (LSP)**, from Barbara Liskov: objects of a subtype must be usable wherever the supertype is expected **without breaking correctness**. Subtypes must honour the parent's **contract**: they may not strengthen preconditions (demand more from callers), weaken postconditions (promise less) or break invariants. The classic violation is `Square extends Rectangle`: code that sets width to 5 and height to 4 expects area 20, but a square that keeps sides equal returns 16. Another is a subclass that throws `UnsupportedOperationException` for methods its parent supports. The **Interface Segregation Principle (ISP)**: clients should not be forced to depend on methods they do not use. A fat `Worker` interface with `work()`, `eat()` and `attendMeeting()` forces a `Robot` to implement `eat()`. Split it into small, role-based interfaces (`Workable`, `Feedable`) so each class implements only what makes sense and clients depend only on what they call.

## An LSP violation and an ISP fix

Square breaks callers that rely on Rectangle's contract; small interfaces avoid fake methods.

```java
class Rectangle {
    protected int width, height;
    void setWidth(int w)  { width = w; }
    void setHeight(int h) { height = h; }
    int area() { return width * height; }
}

class Square extends Rectangle {               // LSP violation
    @Override void setWidth(int w)  { width = height = w; }
    @Override void setHeight(int h) { width = height = h; }
}

void resize(Rectangle r) {
    r.setWidth(5);
    r.setHeight(4);
    assert r.area() == 20;                      // fails for a Square (area 16)
}
// better: make Square and Rectangle separate immutable Shapes

// ISP: small interfaces instead of one fat one
interface Printer { void print(Document d); }
interface Scanner { Document scan(); }
class BasicPrinter implements Printer { public void print(Document d) { } }
class OfficeMachine implements Printer, Scanner {
    public void print(Document d) { }
    public Document scan() { return new Document(); }
}
```

## A replacement driver

If your regular driver is replaced, the substitute must still stop at red lights and take you where you asked. A "driver" who refuses to drive on highways is not a valid substitute, even with the same uniform.

**Quiz:** Which is a sign of a Liskov Substitution Principle violation?

- [ ] A subclass adds a new helper method
- [x] A subclass throws UnsupportedOperationException for a method the parent supports
- [ ] A subclass overrides toString
- [ ] A class implements two interfaces

*Answer:* A subclass throws UnsupportedOperationException for a method the parent supports. Refusing behaviour the parent promises breaks substitutability.
