Principio di sostituzione di Liskov e linguaggi prototipici

0

I linguaggi prototipo forniscono un rimedio al problema di Liskov?

Quindi il mio modo di vedere è questo: una sottoclasse è strettamente accoppiata alla sua superclasse e questo crea sottili effetti collaterali quando si usano tipi polimorfi.

Quindi questo può essere risolto con linguaggi prototipici nel senso che le classi ereditano da una copia della superclasse invece di puntare tutti alla stessa superclasse?

Per fare un esempio, supponiamo di avere questa classe:

class Rectangle
    constructor(width, length)
         this.width = width
         this.height = height

    function double_width()
         this.width = this.width * 2

E ora il programma usa i rettangoli per fare affari o qualsiasi cosa debba fare:

function Main
    Rectangles[] all_rectangles_in_program = new Rectangles[]
    all_rectangles_in_program.append(new Rectanlge(5, 10))
    do_some_buisness_logic(all_rectangles_in_program)

E quindi qualcuno in futuro deve aggiungere una nuova funzione:

class Square inherits Rectangle
    constructor(side_length)
       super(side_length, side_length)

    function double_width()
        this.width = this.width * 2
        this.length = this.length * 2


// MAIN HAS BEEN CHANGED BY OUR COLLEAGUE IN THE FUTURE

function Main
    Rectangles[] all_rectangles_in_program = new Rectangles[]
    all_rectangles_in_program.append(new Rectangle(5, 10))

    Square s = new Square(10)                         <--- new code
    all_rectangles_in_program.append(s)               <--- new code

    do_some_business_logic(all_rectangles_in_program)

Il problema è che il quadrato sovrascrive la funzione double_width ma introduce un effetto collaterale che il rettangolo non aveva e cioè che quando cambi la larghezza ora cambia anche la lunghezza. Questo è un problema perché il programma originale do_some_business_logic può aver fatto affidamento da qualche parte sul fatto che la lunghezza di un rettangolo non cambia quando si cambia la sua larghezza. Ricorda che l'array all_rectangles_in_program è di tipo polimorfico e il codice originale do_some_business_logic non sa se si tratta di rettangoli o quadrati in esso. Il sistema run-time decide quale versione di double_width chiamare.

Quindi la mia domanda è: l'eredità prototipica allevia questo problema perché non si eredita una superclasse in tutto il programma ma invece si eredita la propria copia della superclasse?

In caso negativo, qual è il vantaggio dei linguaggi prototipici rispetto alle lingue basate sulla classe?

    
posta Jenia Ivanov 11.01.2017 - 02:08
fonte

2 risposte

2

Tutti i quadrati sono rettangoli ma non tutti i rettangoli sono quadrati.

Hai violato il vincolo cronologico di LSP.

    
risposta data 12.01.2017 - 10:06
fonte
0

Il problema è nel tuo progetto.

La tua funzione double_width nella classe Square non raddoppia la larghezza, ma raddoppia entrambe le dimensioni.

Quindi non è affatto double_width e non può sovrascrivere il metodo genitore ... È vietato per Square solo a doppia larghezza.

Devi avere un metodo come double_dimensions , in parent o in quadrato.

    
risposta data 11.01.2017 - 02:21
fonte