Es gibt eine Klasse LinkedList mit Funktionen wie add_first (), add_last (), add_after (), remove_first (), remove_last () und remove ().
Jetzt gibt es einen Klassenstapel, der Funktionen wie push (), pop (), peek () oder top () bereitstellt. Um diese Methoden zu implementieren, werden die LinkedList-Klassenmethoden erweitert. Handelt es sich um eine Verletzung des Liskov-Substitutionsprinzips?
Betrachten Sie beispielsweise den Fall add_after (), um einen Knoten an der n-ten Position einer verknüpften Liste hinzuzufügen. Dies kann in der Basisklasse erfolgen, jedoch nicht in der Stack-Klasse. Werden hier Nachbedingungen abgeschwächt oder ändern Sie die Methode add_after (), um sie an die Spitze des Stapels zu setzen?
Auch wenn nicht eine Verletzung, ist das schlechtes Design? Und wie würden Sie die Stack-Funktionalität mithilfe der LinkedList-Klasse implementieren?
LinkedList
? Vielleicht möchten Sie den Rat eines bestimmten Joshua Bloch (der eine wichtige Rolle beim Entwerfen des Java-Kollektions-Frameworks spielte) befolgen, als er sagte: "Komposition vor Vererbung" - HabenLinkedList
Sie vielleicht eine in Ihrer Stapelklasse, aber erweitern Sie sie nicht wirklich?LinkedList
, das die Arbeit hinter den Kulissen erledigt (Komposition). Auf diese Weise können Benutzer Ihres Codes nicht versehentlich einen Stapel verwenden, für den sie eine Liste benötigten, oder umgekehrt.Antworten:
Nein. Es ist vollkommen in Ordnung, Methoden in einem Subtyp hinzuzufügen.
Dies ist eine Verletzung des LSP. Der LSP sagt, dass Instanzen eines Subtyps durch Instanzen eines Supertyps ersetzt werden müssen, ohne die gewünschten Eigenschaften eines Programms zu ändern. Wenn ein Subtyp eine Methode entfernt, stürzt jeder Code ab, der diese Methode aufruft (oder eine
NoMethodError
Ausnahme oder etwas in dieser Richtung). "Nicht abstürzen" ist eindeutig eine wünschenswerte Eigenschaft.Das Ändern der
add_after()
Methode auf diese Weise stellt einen Verstoß gegen die History-Regel (die wichtigste der Regeln!) Dar und hilft daher nicht, den Verstoß gegen den LSP zu beheben.Durch die Verwendung von Komposition.
HINWEIS: Alles, was ich oben geschrieben habe , gilt nur für Sprachen, die Untertypen und Unterklassen verwechseln! Beim LSP geht es um Untertypen , nicht um Unterklassen. In einer Sprache, die die beiden nicht verwechselt, ist es durchaus akzeptabel,
Stack
eine Unterklasse von zu erstellenLinkedList
, sofern Sie sie nicht zu einem Untertyp von machenLinkedList
.quelle
Da Jörg W. Mittag bereits alles angesprochen hat, möchte ich nur auf den folgenden Teil eingehen:
Grundsätzlich hängt es von Ihrem Vertrag ab, ob eine Hierarchie gegen LSP verstößt. Also, welchen Vertrag hat
add_after
das? Wenn es so verrückt klingt, wie "Add a node at the n-th position oder at the top", dann ist die Post-Bedingung erfüllt, LSP wird nicht verletzt. Andernfalls liegt eine LSP-Verletzung vor.quelle