Principio di sostituzione di Liskov: Se il sottotipo ha implementato qualche comportamento extra, che non è presente nel tipo, allora questa violazione di LSP?

7

Nella mia ricerca di scrivere meglio, codice più pulito, sto imparando i principi SOLID. In questo, LSP si sta rivelando poco difficile da comprendere correttamente.

Il mio dubbio è se avessi alcuni metodi extra nel mio sottotipo, S, che non erano presenti nel tipo, T, sarà sempre una violazione di LSP? Se sì, allora come faccio a extend delle mie classi?

Ad esempio, supponiamo di avere un tipo Bird . E i suoi sottotipi sono Eagle e Humming Bird . Ora entrambi i sottotipi hanno un comportamento comune come Bird . Ma Eagle ha anche un buon comportamento predatorio (che non è presente in generale Bird type), che voglio usare . Quindi, ora non potrò fare questo:

Bird bird = new Eagle();

Quindi sta dando a Eagle quei comportamenti extra che spezzano LSP?

Se sì, questo significa che non posso estendere le mie classi perché ciò causerebbe una violazione LSP?

class Eagle extends Bird {
   //we are extending Bird since Eagle has some extra behavior also
}

Le estensioni delle classi dovrebbero essere consentite conformemente al principio Aperto / Chiuso?

Grazie in anticipo per la risposta! Come puoi vedere chiaramente, LSP mi ha confuso come qualsiasi cosa.

Modifica: Segnala questa risposta SO In questo di nuovo, quando Car ha un comportamento aggiuntivo come ChangeGear , viola la LSP. Allora, come possiamo estendere una classe, senza violare LSP?

    
posta user270386 03.05.2018 - 10:17
fonte

2 risposte

10

My doubt is what if I have some extra methods in my subtype, S, which were not there in type, T, will this always be violation of LSP?

Risposta molto semplice: no.

Il punto dell'LSP è che S dovrebbe essere sostituibile per T . Quindi se T implementa una funzione delete , S dovrebbe implementarlo anch'esso e dovrebbe eseguire un delete quando viene chiamato. Tuttavia, S è libero di aggiungere funzionalità aggiuntive oltre a quelle fornite da T . I consumatori di T , quando hanno dato un S non sono a conoscenza di questa funzionalità extra, ma possono esistere per i consumatori di S direttamente da utilizzare.

Un esempio di esempi di come il principio possa essere violato potrebbe essere:

class T
{
    bool delete(Item x)
    {
        if (item exists)
        {
            delete it
            return true;
        }
        return false;
    }
}

class S extends T
{
    bool delete(Item x)
    {
        if (item doesn't exist)
        {
            add it
            return false;
        }
        return true;
    }
}

Risposta leggermente più complessa: no, a condizione che non inizi a influenzare lo stato o altri comportamenti previsti del tipo base.

Ad esempio, la seguente è una violazione:

class Point2D
{
    private readonly double _x;
    private readonly double _y;

    public virtual double X => _x;
    public virtual double Y => _y;

    public Point2D(double x, double y) => (_x, _y) = (x, y);
}

class MyPoint2D : Point2D
{
    private double _x;
    private double _y;

    public override double X => _x;
    public override double Y => _y;

    public MyPoint2D(double x, double y) : 
        base(x, y) => (_x, _y) = (x, y);

    public void Update(double x, double y) => (_x, _y) = (x, y);
}

Il tipo, Point2D , è immutabile; il suo stato non può essere cambiato. Con MyPoint2D , ho deliberatamente aggirato tale comportamento per renderlo mutabile. Questo interrompe il vincolo della cronologia di Point2D e quindi è una violazione dell'LSP.

    
risposta data 03.05.2018 - 10:21
fonte
3

Certo che no. Se l'oggetto Eagle può essere utilizzato da qualsiasi codice che si aspetta un uccello o sottoclasse e si comporta come un uccello dovrebbe comportarsi, stai bene.

Ovviamente il comportamento di Eagle può essere usato solo dal codice che è consapevole che si tratta di un tale oggetto. Ci aspetteremmo che alcuni codici creino esplicitamente un oggetto Eagle e lo utilizzino come oggetto Eagle, pur essendo in grado di utilizzare qualsiasi codice che si aspetta oggetti Bird.

    
risposta data 03.05.2018 - 11:35
fonte

Leggi altre domande sui tag