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.