Gilt das Liskov-Substitutionsprinzip auch für Klassen, die eine Schnittstelle implementieren?

17

LSP gibt an, dass Klassen für ihre Basisklassen substituierbar sein sollten, was bedeutet, dass abgeleitete und Basisklassen semantisch äquivalent sein sollten.

Aber gilt LSP auch für Klassen, die eine Schnittstelle implementieren? Mit anderen Worten, wenn eine von einer Klasse implementierte Schnittstellenmethode sich semantisch von den Erwartungen des Benutzers unterscheidet, würde dies als Verstoß gegen LSP angesehen werden?

user1483278
quelle
7
Ja. Genau die gleichen Gründe und Ergebnisse wie bei einer Verletzung des LSP, wenn es sich um eine Schnittstelle, eine abstrakte Klasse oder eine vollständige Klasse handelt. Bei LSP geht es darum, die Erwartungen festzulegen und zu erfüllen, damit die Verbraucher Ihre Typen allgemein behandeln können.
Jimmy Hoffa
5
Im Großen und Ganzen (ich kenne die Unterschiede, aber ich verallgemeinere sie hier) sind Schnittstellen etwas analog zu reinen abstrakten Klassen (C ++ - Term), und daher sollte Liskov auf Schnittstellen und die Klassen, die sie implementieren, angewendet werden.
Jesse C. Slicer
3
NB die Formulierung des LSP, die ich kenne, spricht eher von Subtypen als von abgeleiteten und Basisklassen. Ich gehe aus gutem Grund davon aus, dass keiner der Gründe für die Vererbung spezifisch ist und auch für jede andere Art von Untertypisierung gilt.

Antworten:

17

Wenn eine von einer Klasse implementierte Schnittstellenmethode sich semantisch von den Erwartungen des Benutzers unterscheidet, wird dies als Verstoß gegen LSP angesehen?

Wenn sich die Implementierung semantisch von dem Verhalten unterscheidet, das durch die Invarianten der Schnittstelle und die Vor- und Nachbedingungen ihrer Methoden dokumentiert wird, lautet die Antwort "Ja". Dies wäre eine Verletzung des LSP. Das Prinzip legt die Regeln für die Abstraktion und ihre Implementierungen fest, ohne dass die Abstraktionsseite in Form einer Klasse vorliegen muss.

Wenn wir jedoch darüber sprechen, was Benutzer erwarten , lautet die Antwort "nicht unbedingt": Die Benutzer haben das Recht, falsche Erwartungen zu haben.

dasblinkenlight
quelle
"Wenn sich die Implementierung semantisch von dem durch die Invarianten der Schnittstelle dokumentierten Verhalten unterscheidet" Können Sie erläutern, was Sie unter "Invarianten der Schnittstelle" verstehen?
user1483278
3
Hier @ user1483278 ist ein Artikel über Typ Invarianten . Der Artikel nennt sie "Klasseninvarianten", aber die Beschreibung gilt auch für Schnittstellen. Invarianten sind Bedingungen, die bei der Erstellung festgelegt und während der gesamten Lebensdauer einer Instanz aufrechterhalten werden. Wenn beispielsweise eine Schnittstelle eine Eigenschaft hat Name, die nicht festgelegt werden kann null, obj.Name != nullwird von einer Invariante dieser Schnittstelle gesprochen.
dasblinkenlight
1
In der Regel ist es bei der Erörterung von Invarianten möglich, einen Code zu schreiben, um zu überprüfen, ob die Invariante über die gesamte Lebensdauer des Objekts erhalten bleibt. Es ist jedoch in der Regel einfacher, die Invariante im Klartext zu beschreiben.
rwong