Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Java: Liskov Substitution Principle, SOLID, inheritance, polymorphism, object-oriented design

В чем суть принципа Liskov Substitution?

Вопрос проверяет понимание принципа подстановки Барбары Лисков (LSP), ключевого принципа SOLID, который обеспечивает корректность наследования и полиморфизма в объектно-ориентированном программировании.

Короткий ответ

Принцип подстановки Лисков гласит, что объекты базового класса должны быть заменяемы объектами производного класса без изменения корректности программы. Это означает, что наследник должен дополнять, а не изменять поведение родителя. Например, если у вас есть класс Прямоугольник, то класс Квадрат, наследующий от него, не должен нарушать логику работы с шириной и высотой. Нарушение LSP приводит к хрупкому коду и неожиданным ошибкам.

Длинный ответ

Принцип подстановки Лисков (LSP) — это третий принцип SOLID, который формализует, что отношения наследования должны быть логически корректными. Он утверждает, что если S является подтипом T, то объекты типа T могут быть заменены объектами типа S без изменения каких-либо желательных свойств программы (корректности, выполнения задач и т.д.).

Основная идея

Наследование должно означать "является" (is-a) в поведенческом смысле, а не только в структурном. Производный класс должен выполнять все контракты (ожидаемое поведение, инварианты, постусловия) базового класса. Он может расширять функциональность, но не должен её ослаблять или ужесточать предварительные условия.

Классический пример нарушения

Рассмотрим пример с прямоугольником и квадратом. С математической точки зрения квадрат — это прямоугольник. Однако в коде это часто приводит к проблемам.

class Rectangle {
    protected width;
    protected height;
    setWidth(w) { this.width = w; }
    setHeight(h) { this.height = h; }
    getArea() { return this.width * this.height; }
}

class Square extends Rectangle {
    // Нарушение LSP: изменение поведения сеттеров
    setWidth(w) {
        this.width = w;
        this.height = w; // Побочный эффект
    }
    setHeight(h) {
        this.height = h;
        this.width = h; // Побочный эффект
    }
}

function testArea(rect) {
    rect.setWidth(5);
    rect.setHeight(4);
    // Ожидаемая площадь: 20
    console.log(rect.getArea()); // Для Square будет 16!
}

const rect = new Rectangle();
testArea(rect); // 20 - OK
const sq = new Square();
testArea(sq);   // 16 - Нарушение ожиданий!

Код, работающий с Rectangle, ожидает, что ширина и высота изменяются независимо. Класс Square нарушает этот контракт, поэтому он не является корректным подтипом с точки зрения LSP.

Как соблюдать LSP

  • Проектируйте иерархии, ориентируясь на поведение, а не на данные.
  • Избегайте переопределения методов так, что они делают что-то принципиально иное или ужесточают/ослабляют условия.
  • Используйте композицию вместо наследования, если отношения "является" сомнительны.
  • Пишите модульные тесты для базового класса — они должны проходить и для всех производных классов.

Где применяется

LSP критически важен при проектировании библиотек, фреймворков и любых систем с полиморфными вызовами. Он позволяет безопасно использовать шаблоны проектирования, такие как Стратегия или Фабричный метод, и писать обобщённый код, работающий с базовыми типами.

Вывод: Принцип подстановки Лисков следует применять всегда при проектировании иерархий классов, чтобы код был предсказуемым, расширяемым и устойчивым к изменениям. Он особенно полезен в крупных проектах, где разные модули взаимодействуют через абстракции.

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Java

    Java

  • C#

    C#

Ключевые слова

#Liskov Substitution Principle

#SOLID

#inheritance

#polymorphism

#object-oriented design

Подпишись на React Developer в телеграм

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию