TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #340 6.84K
L is for Liskov

— SOLID принципы знаете?

Думаю, нет разработчика, который не слышал на собеседовании такой вопрос.

Расшифровку знают многие. А вот практические знания часто ограничиваются Single Responsibility и Interface Segregation.

Как применять остальные буквы в ежедневной работе — не всегда понятно. Больше всего вопросов возникает насчёт L — Liskov Substitution Principle. О нём и будет сегодняшний пост.

Полное определение звучит так:

Пусть q(x) является свойством верным относительно объектов x некоторого типа T. Тогда q(y) также должно быть верным для объектов y типа S, где S является подтипом типа T.

По-простому: если заменить класс А на подкласс B, то система будет работать корректно и без неожиданных сайд-эффектов.

A service1 = new A();
A service2 = new B();

Для наблюдателя service1 и service2 ведут себя совершенно одинаково. Класс-наследник дополняет поведение родителя, а не замещает его. В результате система работает более предсказуемо.

Как это выглядит на практике:

1️⃣ Выходной тип метода в наследнике такой же как у родителя или расширенный

Базовый класс: Info getInfo()

Наследник:
✅ BigInfo getInfo()
❌ Object getInfo()

2️⃣ Подклассы не бросают дополнительных исключений, но могут уменьшить их список

Базовый класс: void save() throws FileNotFoundException

Наследник:
✅ void save()
❌ void save() throws FileNotFoundEx, InterruptedEx

Java — типизированный язык, поэтому пункты 1 и 2 контролируются компилятором.

3️⃣ Типы входных параметров те же или менее строгие. Пункт для общего понимания, тк для Java это неприменимо

Базовый класс: void add(Account acc)

Наследник:
✅ void add(Object acc)
❌ void add(AdminAccount acc)

Следующие пункты компилятор уже не проверит, это целиком ответственность программиста.

4️⃣ Метод подкласса делает то же, что и метод базового класса

Базовый класс: метод countVisitors считает пользователей

Наследник:
✅ Считает пользователей чуть по-другому
❌ Считает пользователей, обновляет статистику, сохраняет результат в БД

5️⃣ Метод наследника взаимодействует с теми же сущностями:
▪️ Метод родителя увеличивает счётчик - подкласс тоже увеличивает
▪️ Метод родителя не меняет поле - подкласс тоже не меняет
▪️ Метод родителя вызывает другие методы в определённом порядке - подкласс делает то же самое

А что можно вообще?

Если в подклассе объявлены новые поля, то методы подкласса могут делать с ними что угодно. На этом всё🙂

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

Нарушения принципа подстановки — повод пересмотреть иерархию наследования или совсем от неё отказаться.
  • 👍 7
  • ❤ 3
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
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 →