Do prototypical languages provide a remedy from Liskov's problem?
So the way I see this is: a subclass is very tightly coupled with it's superclass and this creates subtle side effects when polymorphic types are used.
So can this be remedied by prototypical languages in the sense that classes inherits from a copy of the superclass instead of all pointing to the same one superclass?
To give an example, suppose I have this class:
class Rectangle
constructor(width, length)
this.width = width
this.height = height
function double_width()
this.width = this.width * 2
And now the program uses the rectangles to do business or whatever it needs to do:
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)
And then someone in the future needs to add a new feature:
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)
The problem is that square overrides the function double_width but introduces a side effect that rectangle didn't have namely that when you change the width now the length changes too. This is a problem because the original program do_some_business_logic
may have relied somewhere on the fact that the length of a rectangle doesn't change when you change it's width. Remember that the array all_rectangles_in_program
is polymorphic type and the original code do_some_business_logic
doesn't know if these are rectangles or squares in it. The run-time system decides which version of double_width
to call.
So my question is, does prototypical inheritance alleviate this problem because you don't inherit one superclass everywhere in the program but instead inherit your own copy of the superclass?
If not, then what's the advantage of prototypical languages over class based languages?