LSP vieta di violare i contratti di un supertipo in un sottotipo, non vieta di cambiare il comportamento di metodo (entro i limiti di tale contratto).
Ad esempio, supponiamo di avere una superclasse Report
, associata a un certo oggetto Foo
, con un metodo ToString()
, e sottotipi HTMLReport
, XMLReport
e TextReport
. Supponiamo inoltre che Report
non sia astratto e l'implementazione predefinita di ToString()
è di restituire la stringa vuota. Ora definisci un contratto nel modo seguente:
-
ToString()
deve consegnare una stringa con una rappresentazione testuale di Foo
in un determinato formato di testo (e la stringa vuota se il formato non è stato definito fino ad ora).
-
ToString()
non muta l'oggetto Report
-
ToString()
non deve mai generare un'eccezione
Quindi le sottoclassi possono facilmente sovrascrivere il metodo ToString
, ognuno dei quali implementa un comportamento diverso, ma tutti seguono perfettamente l'LSP.
D'altra parte, se il tuo contratto sarebbe
-
ToString()
deve sempre restituire la stringa vuota
quindi sovrascrivendolo e restituisci qualcosa di diverso viola l'LSP - ma un simile contratto ovviamente non avrebbe molto senso per qualsiasi scenario del mondo reale.