In languages with dynamic typing, the use of polymorphism may trigger errors on a super-class.
I will try to explain my question with a simple example: Supposing a language with dynamic typing (like ECMAScript) and the following class structure:
class A{
private idA;
public A(){
idA=0;
}
public foo(){
update();
if (this.idA!=3) Throws new Exception(" What is happening? ");
}
private update(){
this.idA = 3;
}
}
class B extends A{
private idB;
public B(){
super();
idB=0;
}
public foo(){
super.foo();
// Any operation between A::update and B::update()
if (this.idB!=0) Throws new Exception("hmmm, that could not happend!");
update();
}
private update(){
this.idB = 5;
}
}
In this very simple example, when i create an object of the class B, B::foo() call the parent A::foo(), which call "update". The object is an instance of B, so the "update" functions called is B::update, after that, in B::foo, the update function is again called (B::update). The final result is that A::update is never called, and idA still 0.
The class A work correctly when used alone, but after to extend it with B, the function foo() fail.
What is the correct solution this problem:
1) Force the class A to call A::update , that mean an ugly code every call to his own function (protect the super-class):
A::foo(){
A::update();
if (this.idA!=3) Throws new Exception(" What is happening? ");
}
2) B::update is an extension of A::update, so B::update must call itself the parent function (prepare the sub-class, and deal with problems):
B::foo(){
super.foo();
... // Any operation that must be performed between A::update and B::update
}
B::update(){
super.update();
this.idB = 5;
}
But in this case is the A::foo which call update, not the B::foo. That mean others problems.
3) Any other solution.
As a summary:
How to protect the super-class code against polymorphism?
- Add protections into the super-class.
- Deal with these problem creating the child-class
- The language must do that! (do not know if it is possible with dynamically typed languages)
I am looking for a very theoretical /canonical solution to this question.
EDITED: to take the problem out of the constructor and clarify some points.