Ответ
Принцип подстановки Лисков (LSP) — это один из принципов SOLID. Он гласит, что объекты базового класса должны быть заменяемыми объектами его подклассов без изменения корректности программы. Нарушение LSP ведет к хрупкости кода и неожиданным ошибкам.
Сложности соблюдения LSP: Соблюдать LSP сложно, когда наследование используется для повторного использования кода, а не для выражения истинного отношения "является" (is-a).
Классический пример нарушения LSP:
class Rectangle {
private int width;
private int height;
public void setWidth(int w) { this.width = w; }
public void setHeight(int h) { this.height = h; }
public int area() { return width * height; }
}
class Square extends Rectangle {
@Override
public void setWidth(int w) {
super.setWidth(w);
super.setHeight(w); // Нарушение контракта Rectangle!
}
// Аналогично переопределяется setHeight
}
Клиентский код, ожидающий, что setWidth и setHeight работают независимо, сломается при работе с Square.
Как соблюдать LSP на практике:
- Четкий контракт: Базовый класс должен явно или неявно определять инварианты, пред- и постусловия для своих методов.
- Предпочитать композицию: Если семантика подкласса отличается, лучше использовать композицию (
SquareсодержитRectangle). - Избегать усиления предусловий и ослабления постусловий в подклассах.
- Не изменять типы возвращаемых значений или исключений непредсказуемым образом.
Соблюдение LSP требует тщательного проектирования иерархий, но значительно упрощает расширение и поддержку системы.