In che modo il rafforzamento delle precondizioni e l'indebolimento delle postcondizioni violano il principio di sostituzione di Liskov?


19

Ho letto che il principio di sostituzione di Liskov è violato se:

  1. I requisiti sono rafforzati, o

  2. Le post-condizioni sono indebolite

Ma non riesco ancora a capire come questi due punti violerebbero il principio di sostituzione di Liskov. Qualcuno può spiegare con un esempio. In particolare, come una delle condizioni di cui sopra potrebbe causare una situazione in cui un oggetto di sottoclasse non può essere sostituito con un oggetto di superclasse?

Risposte:


29
  1. Supponiamo che la tua baseclass funzioni con un membro int. Ora il tuo sottotipo richiede che int sia positivo. Questo è un prerequisito rafforzato, e ora qualsiasi codice che ha funzionato perfettamente prima con ints negativi è rotto.

  2. Allo stesso modo, si assume lo stesso scenario, ma la classe base utilizzata per garantire che il membro sarebbe positivo dopo essere stato chiamato. Quindi il sottotipo modifica il comportamento per consentire ints negativi. Il codice che funziona sull'oggetto (e presuppone che la post-condizione sia un int positivo) è ora interrotto poiché la post-condizione non viene confermata.

Questi sono ovviamente esempi banali, ma il concetto vale. Cose come lasciare una connessione file / database aperta sono un esempio di post-condizione semplificata che porta a problemi.


1

inserisci qui la descrizione dell'immagine

Invariante - Modello di SelfDrivingVehicle che rimane invariato in tutti i sottotipi, ovvero nell'ordine in cui esegue i comportamenti ignorati per raggiungere la destinazione.

Supponiamo un altro metodo qui

           -List<SelfDrivingVehicle> vehicles 
           +Add(SelfDrivingVehicle vehicle)
            vehicles.add(vehicle)

Prerequisito - SelfDriveVehicle il Tipo di base non ha veicoli (qui il contesto è Add) ed è in Weakened Precondition che non può essere modificato da nessuno dei suoi sottotipi cambiando i veicoli di proprietà e rafforzandolo esplicitamente. Uno dei sottotipi può solo invocare Aggiungi.

Postcondizione - Una volta invocato Aggiungi, il tipo di base è in Postcondizione rafforzata che non può essere indebolito dai sottotipi alterando il valore dei veicoli.

Lo stato del tipo di base ritorna allo stato originale una volta richiamato il comportamento Aggiungi.


-1

Questo esempio è praticamente battuto a morte, ma considera la possibilità Quadrato / Rettangolo o Cerchio / Ellisse. Supponiamo di avere una classe base Rectangle che definisce un oggetto con lunghezza e larghezza. Se hai una classe Square che eredita la classe Rectangle, avrebbe una regola nel suo setter / getter che richiederebbe che qualsiasi modifica di lunghezza o larghezza ne altererebbe la controparte. Questi requisiti dimensionali rafforzano le pre-condizioni perché un rettangolo sostituito con un quadrato mancherebbe a questi requisiti dimensionali. Supponiamo di invertire l'eredità in modo tale che un Rettangolo erediti un Quadrato, indebolendo le condizioni post rilassando i requisiti dimensionali per consentire al Rettangolo di comportarsi in modo indipendente.

Tuttavia, se si dovesse rimuovere la capacità di cambiamento dimensionale, il principio di sostituzione vale perché se né un rettangolo né un quadrato possono cambiare le dimensioni, allora hanno le stesse condizioni pre e post indipendentemente dall'eredità. Entrambi hanno una lunghezza, entrambi hanno una larghezza e nessuno dei due può modificare tali valori.

rif: Wikipedia - http://it.wikipedia.org/wiki/Liskov_substitution_principle


1
Purtroppo questo esempio non ha nulla a che fare con la verifica formale. Non ci sono contratti.
Frank Hileman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.