TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #557 1.09K
День четыреста шестидесятый. #DesignPatterns
Принципы SOLID.
3. Принцип подстановки Лисков (LSP)
«Должна существовать возможность использовать объекты производного класса вместо объектов базового класса. Это значит, что объекты производного класса должны вести себя согласованно, согласно контракту базового класса». (Уорд Каннингем. Liskov Substitution Principle).
Наследование обычно моделирует отношение «ЯВЛЯЕТСЯ» (IS-A Relationship) между классами. Говорят, что экземпляр наследника также ЯВЛЯЕТСЯ экземпляром базового класса, что выражается в возможности использования экземпляров наследника везде, где ожидается использование базового класса. Данный вид наследования называется также наследованием подтипов. Принцип подстановки Лисков призван помочь в корректной реализации этого вида наследования, или отказаться от наследования, если его корректная реализация невозможна.

Для чего нужен принцип подстановки Лисков
Основной смысл любой иерархии наследования в том, что она позволяет использовать базовые классы полиморфным образом, не задумываясь о том, экземпляр какого конкретного класса был передан. С одной стороны, любая реализация должна следовать некоторому абстрактному протоколу или контракту, а с другой — она должна иметь возможность выбрать конкретный способ реализации этого протокола. Контракт описывает ожидаемое видимое поведение абстракции, оставляя реализации решать, каким образом это поведение будет реализовано. Если же реализация (то есть наследники) не будет знать об этом протоколе или не будет ему следовать, то в приложении мы будем вынуждены обрабатывать конкретную реализацию специальным образом, что сводит на нет преимущества использования наследования и полиморфизма.

Квадраты и прямоугольники
Является ли квадрат прямоугольником? Это зависит от того, какое поведение мы будем приписывать фигурам, т.е. от спецификации или контракта (ожидаемого поведения) этих сущностей. С точки зрения математики квадрат является прямоугольником, но актуально ли это отношение для классов? Попытаемся сформулировать контракты этих классов:
- Прямоугольник: ширина и высота положительны.
- Квадрат: ширина и высота положительны и равны.

Поскольку у квадрата все стороны равны, то изменение его ширины должно приводить к изменению высоты и наоборот. Это значит, контракт свойств ширины и высоты квадрата становится несогласованным с контрактом этих свойств прямоугольника. С точки зрения клиента прямоугольника свойства полностью независимы, а значит, замена прямоугольника квадратом во время исполнения нарушит это предположение клиента.
Но это не значит, что данная иерархия наследования является невозможной. Квадрат перестаёт быть нормальным прямоугольником, только если квадрат и прямоугольник являются изменяемыми. Если сделать их неизменяемыми, проблема с нарушением поведения клиентского кода при замене прямоугольников квадратами пропадет.

Данный пример показывает несколько важных моментов:
1. Что наличие контракта позволяет чётко понять, нарушает ли производный класс принцип LSP.
2. Пользу неизменяемости в ООП: контракт неизменяемых типов проще, поскольку контролируется лишь конструктором и инвариантом класса.
3. Почему некоторые специалисты рекомендуют, чтобы классы были либо абстрактными, либо запечатанными (sealed) и не было возможности создавать экземпляры классов из середины иерархии наследования. Например, в этом случае можно выделить промежуточный абстрактный класс «четырехугольник», от которого уже наследуются квадрат и прямоугольник.
>>>
More from @netdeveloperdiary
  1. Sep 30, 2026Post #3356
  2. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  3. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  4. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
  5. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  6. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →