W jaki sposób wzmocnienie warunków wstępnych i osłabienie warunków wtórnych narusza zasadę substytucji Liskowa?

19

Czytam, że zasada substytucji Liskowa jest naruszona, jeśli:

  1. Warunki wstępne są wzmocnione, lub

  2. Warunki dodatkowe są osłabione

Ale jeszcze nie rozumiem, w jaki sposób te dwa punkty naruszałyby zasadę substytucji Liskowa. Czy ktoś może wyjaśnić przykład. W szczególności, w jaki sposób którykolwiek z powyższych warunków spowodowałby sytuację, w której obiekt podklasy nie mógłby zostać zastąpiony obiektem nadklasy?

Maniak
źródło

Odpowiedzi:

29
  1. Załóżmy, że twoja klasa podstawowa działa z członkiem int. Teraz twój podtyp wymaga, aby int był dodatni. Jest to wzmocnione warunki wstępne, a teraz każdy kod, który wcześniej działał doskonale z ujemnymi intami, został uszkodzony.

  2. Podobnie, załóżmy ten sam scenariusz, ale klasa podstawowa zastosowana w celu zagwarantowania, że ​​element członkowski będzie dodatni po wywołaniu. Następnie podtyp zmienia zachowanie, aby umożliwić ujemne wartości int. Kod, który działa na obiekcie (i zakłada, że ​​warunek końcowy jest dodatnią liczbą całkowitą) jest teraz uszkodzony, ponieważ warunek końcowy nie jest podtrzymywany.

Są to oczywiście trywialne przykłady, ale koncepcja ma zastosowanie. Rzeczy takie jak pozostawienie otwartego połączenia pliku / bazy danych jest przykładem złagodzenia warunku końcowego, który prowadzi do problemów.

Telastyn
źródło
1

wprowadź opis zdjęcia tutaj

Niezmienny - szablon pojazdu SelfDriving, który pozostaje niezmieniony we wszystkich podtypach, tj. W kolejności, w której wykonuje nadpisane zachowania, aby dotrzeć do miejsca docelowego.

Załóżmy tutaj jeszcze jedną metodę

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

Warunek wstępny - SelfDriveVehicle typ podstawowy nie ma w nim pojazdów (tutaj kontekst to Dodaj), a jego warunek jest osłabiony, który nie może zostać zmieniony przez żaden z jego podtypów poprzez zmianę pojazdów własności i wzmocnienie go w sposób jawny. Każdy z podtypów może wywoływać tylko Add.

Postcondition - Po wywołaniu Add Typ podstawowy jest w Postcondition wzmocnionym, którego nie można osłabić podtypami poprzez zmianę wartości pojazdów.

Stan typu podstawowego powraca do pierwotnego stanu po wywołaniu zachowania dodawania.

Vishal Patwardhan
źródło
-1

Ten przykład jest prawie pobity na śmierć, ale rozważ możliwość Square / Rectangle lub Circle / Ellipse. Załóżmy, że masz klasę bazową Prostokąt, która definiuje obiekt o długości i szerokości. Jeśli masz klasę Square, która dziedziczy klasę Rectangle, w jej seter / getter będzie istniała reguła, która wymagałaby, aby każda zmiana długości lub szerokości zmieniała jej odpowiednik. Te wymagania wymiarowe wzmacniają warunki wstępne, ponieważ prostokąt zastąpiony kwadratem nie spełniałby tych wymagań wymiarowych. Załóżmy, że odwrócisz dziedziczenie, tak aby prostokąt odziedziczył kwadrat, osłabiłbyś warunki pocztowe poprzez złagodzenie wymagań wymiarowych, aby prostokąt mógł zachowywać się niezależnie.

Jeśli jednak chcesz usunąć możliwość zmiany wymiarów, obowiązuje zasada podstawienia, ponieważ jeśli ani prostokąt, ani kwadrat nie mogą zmienić wymiarów, wówczas mają one równe warunki przed i po, niezależnie od dziedziczenia. Oba mają długość, oba mają szerokość i żadne z nich nie może zmienić tych wartości.

ref: Wikipedia - http://en.wikipedia.org/wiki/Liskov_substitution_principle

Joel Etherton
źródło
1
Niestety ten przykład nie ma nic wspólnego z formalną weryfikacją. Brak umów.
Frank Hileman,