Вопрос проверяет понимание принципа подстановки Барбары Лисков (LSP), ключевого принципа SOLID, который обеспечивает корректность наследования и полиморфизма в объектно-ориентированном программировании.
Принцип подстановки Лисков (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 критически важен при проектировании библиотек, фреймворков и любых систем с полиморфными вызовами. Он позволяет безопасно использовать шаблоны проектирования, такие как Стратегия или Фабричный метод, и писать обобщённый код, работающий с базовыми типами.
Вывод: Принцип подстановки Лисков следует применять всегда при проектировании иерархий классов, чтобы код был предсказуемым, расширяемым и устойчивым к изменениям. Он особенно полезен в крупных проектах, где разные модули взаимодействуют через абстракции.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию