Как усиление предусловий и ослабление постусловий нарушают принцип подстановки Лискова?

19

Я читал, что принцип замещения Лискова нарушается, если:

  1. Предпосылки усиливаются, или

  2. Постусловия ослаблены

Но я еще не до конца понял, как эти два пункта нарушают принцип подстановки Лискова. Может кто-нибудь, пожалуйста, объясните на примере. В частности, каким образом любое из вышеперечисленных условий может вызвать ситуацию, когда объект подкласса не может быть заменен объектом суперкласса?

Компьютерщик
источник

Ответы:

29
  1. Предположим, ваш базовый класс работает с членом int. Теперь ваш подтип требует, чтобы int был положительным. Это улучшило предварительные условия, и теперь любой код, который работал отлично до этого с отрицательными значениями, не работает.

  2. Аналогично, предположим, что тот же сценарий, но базовый класс используется, чтобы гарантировать, что член будет положительным после вызова. Затем подтип изменяет поведение, чтобы разрешить отрицательные числа. Код, который работает с объектом (и предполагает, что постусловие является положительным int), теперь нарушается, поскольку постусловие не поддерживается.

Это, конечно, тривиальные примеры, но концепция верна. Такие вещи, как оставление соединения с файлом / базой данных открытым, являются примером ослабленного пост-состояния, которое приводит к проблемам.

Telastyn
источник
1

введите описание изображения здесь

Invariant - Шаблон SelfDrivingVehicle, который остается неизменным во всех подтипах, т.е. в порядке, в котором он выполняет переопределенное поведение для достижения цели.

Давайте предположим еще один метод здесь

           -List<SelfDrivingVehicle> vehicles 
           +Add(SelfDrivingVehicle vehicle)
            vehicles.add(vehicle)

Предварительное условие - SelfDriveVehicle Базовый тип не имеет транспортных средств (здесь контекст является Add) и его в Ослабленном предварительном условии, которое не может быть изменено ни одним из его подтипов путем изменения транспортных средств свойства и усиления его явно. Любой из подтипов может вызывать только Add.

Постусловие - после вызова Add базовый тип находится в усиленном постусловии, которое не может быть ослаблено подтипами путем изменения стоимости транспортных средств.

State of Base Type возвращается в исходное состояние после вызова Add Behavior.

Вишал Патвардхан
источник
-1

Этот пример в значительной степени избит до смерти, но рассмотрим возможность «квадрат / прямоугольник» или «круг / эллипс». Предположим, у вас есть базовый класс Rectangle, который определяет объект с длиной и шириной. Если у вас есть класс Square, который наследует класс Rectangle, в его установщике / получателе будет правило, которое потребует, чтобы любое изменение длины или ширины изменило его аналог. Эти требования к размерам усиливают предварительные условия, потому что прямоугольник, заменяющий квадрат, будет пропускать эти требования к размерам. Предположим, вы изменили наследование так, чтобы Rectangle наследовал квадрат, и вы ослабили бы условия поста, ослабив требования к размерам, чтобы Rectangle мог вести себя независимо.

Тем не менее, если вы удалите возможность изменения размеров, принцип подстановки верен, потому что если ни прямоугольник, ни квадрат не могут изменить размеры, то они имеют одинаковые условия до и после независимо от наследования. Оба имеют длину, оба имеют ширину, и ни один не может изменить эти значения.

ссылка: Википедия - http://en.wikipedia.org/wiki/Liskov_substitution_principle

Джоэл Этертон
источник
1
К сожалению, этот пример не имеет ничего общего с формальной проверкой. Контрактов нет.
Фрэнк Хилман