Ответ
Принцип подстановки Лисков (Liskov Substitution Principle, LSP) — один из пяти принципов SOLID. Он гласит, что объекты производного класса должны быть заменяемы объектами своего базового класса без нарушения корректности программы. Проще говоря, если у вас есть функция, работающая с базовым классом, она должна продолжать корректно работать, если вы передадите ей любой из его наследников.
Суть принципа: Наследование должно означать отношение «является» (is-a) в поведенческом, а не только в структурном смысле. Наследник не должен ужесточать предусловия или ослаблять постусловия методов базового класса.
Классический пример нарушения LSP (Прямоугольник и Квадрат):
// Базовый класс
public class Rectangle
{
public virtual int Width { get; set; }
public virtual int Height { get; set; }
public int Area => Width * Height;
}
// Наследник, нарушающий LSP
public class Square : Rectangle
{
public override int Width
{
set { base.Width = value; base.Height = value; }
}
public override int Height
{
set { base.Width = value; base.Height = value; }
}
}
// Клиентский код, который сломается
public void TestRectangleArea(Rectangle rect)
{
rect.Width = 5;
rect.Height = 4;
Console.WriteLine($"Expected area: 20, Actual area: {rect.Area}"); // Для Square будет 16!
}
Почему это нарушение? Клиентский код TestRectangleArea ожидает, что ширина и высота прямоугольника изменяются независимо. Квадрат же нарушает это поведенческое ожидание, делая их зависимыми.
Как исправить (следовать LSP):
- Избегать неподходящего наследования. Квадрат и прямоугольник могут быть разными сущностями.
- Использовать общий интерфейс или абстрактный класс, если они действительно имеют общее поведение.
public interface IShape
{
int CalculateArea();
}
public class Rectangle : IShape { /* ... */ }
public class Square : IShape { /* ... */ }
Вывод: Следование LSP делает систему более устойчивой к изменениям, позволяет безопасно использовать полиморфизм и избегать скрытых ошибок.
Видео-ответы
▶
▶
▶
▶
▶
▶