Istnieje klasa LinkedList z funkcjami takimi jak add_first (), add_last (), add_after (), remove_first (), remove_last () i remove ()
Teraz istnieje stos klas, który zapewnia funkcje takie jak push (), pop (), peek () lub top (), a do implementacji tych metod rozszerza metody klasy LinkedList. Czy jest to naruszenie zasady substytucji Liskowa?
Na przykład rozważmy przypadek add_after (), aby dodać węzeł w n-tej pozycji listy połączonej. Można to zrobić w klasie podstawowej, ale nie w klasie Stack. Czy warunki są osłabiane tutaj, czy modyfikujesz metodę add_after (), aby dodać ją na górę stosu?
Ponadto, jeśli nie jest to naruszenie, czy ten zły projekt? A jak zaimplementowałbyś funkcjonalność stosu za pomocą klasy LinkedList?
LinkedList
? Być może zechcesz posłuchać rady pewnego Joshua Blocha (który odegrał znaczącą rolę w projektowaniu frameworku kolekcji Java), gdy powiedział: „Wolę kompozycję niż dziedziczenie” - Może maszLinkedList
wewnątrz swojej klasy stosu, ale tak naprawdę go nie rozszerzasz?LinkedList
który wykonuje ciężkie podnoszenie się za kulisy (kompozycja). W ten sposób użytkownicy Twojego kodu nie mogą przypadkowo użyć stosu, w którym potrzebowali listy lub odwrotnie.Odpowiedzi:
Nie. Można dodawać metody w podtypie.
Jest to naruszenie LSP. LSP mówi, że instancje podtypu muszą być zastępowalne dla instancji nadtypu bez zmiany pożądanych właściwości programu. Jeśli podtyp usunie metodę, wówczas dowolny kod wywołujący tę metodę ulegnie awarii (lub otrzyma
NoMethodError
wyjątek lub coś wzdłuż tych linii). Oczywiście „brak awarii” jest pożądaną właściwością.Modyfikacja
add_after()
metody w ten sposób stanowi naruszenie Reguły historii (najważniejsza z zasad!), A tym samym nie pomaga naprawić naruszenia LSP.Używając kompozycji.
UWAGA: Wszystko, co napisałem powyżej, dotyczy tylko języków, które mylą podtytuły i podklasy! LSP dotyczy podtypów , a nie podklas. W języku, którego nie należy mylić dwóch, byłoby to całkowicie dopuszczalne, aby
Stack
podklasyLinkedList
, tak długo, jak nie zrobić to podtyp zLinkedList
.źródło
Ponieważ Jörg W Mittag zajął się już wszystkimi kwestiami, rozwinąłem nieco tę część:
Zasadniczo, gdy pojawia się pytanie, czy jakaś hierarchia narusza LSP, zależy to od tego, jaki kontrakt stanowisz. Więc jaka umowa
add_after
ma? Jeśli to brzmi, jakkolwiek szalone, jak „Dodaj węzeł na n-tej pozycji lub na górze”, to nic ci nie jest, warunek końcowy jest spełniony, LSP nie jest naruszany. W przeciwnym razie jest to naruszenie LSP.źródło