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?