To be completely honest, I'm not sure if that's a bug or if it is intended.. I am going to say it is a bug for the same reasons that parameters and object fields are in the same scope (explained below).. The reason I say this is because unlike C++ or Java, Lape does NOT have virtual functions in the same way.. In other words, the derived class cannot access the parent class's functions that were overloaded. It is most likely due to the fact that lape does not have static functions or even virtual lookup..
Brace yourself for an explanation..
Example:
class T3DPoint //Base class.
{
private:
float x, y, z;
public:
T3DPoint(float X, float Y, float Z) : x(X), y(Y), z(Z) {} //Base class constructor taking 3 parameters.
};
class T3DColourPoint : public T3DPoint //Derived class inheriting from Base class.
{
private:
int colour;
public:
T3DColorPoint(float X, float Y, float Z, int Colour) : T3DPoint(X, Y, Z), colour(Colour) {} //call the super constructor then initialize our own variables.. aka colour..
};
As you can see, we can call the base class's constructor explicitly. In java this is equivalent to the super keyword.
What is the equivalent in Lape then? Let's think about this for a second.
In Lape, we have self keyword to access the current instance of an object:
Bad Code (parameters and objects share the same scope):
type
T3DPoint = record
X, Y, Z : Extended;
end;
procedure T3DPoint.create(X, Y, Z : Extended);
begin
self.X := X;
self.Y := Y;
self.Z := Z;
end;
But does the self keyword really work like the this keyword? No it does not because as you can see above, the parameters are named the same as the object's fields and yet self.X is assigning to itself! It's not actually assigning parameter X to self.X. This was discussed previously and I deemed it as a bug..
The same can be said for functions especially overloaded ones. So how do we call the base class's overloaded function? The idea is to NOT overload! When you overload a function, you create what is called a virtual function and its address is added to what is called the Virtual table or VTable for short.. This allows polymorphism to work..
http://en.wikipedia.org/wiki/Virtual_method_tableWhen the derived class's function is called, it is looked up in the VTable to make sure that it has the right one. If it is NOT overloaded, it isn't added to the VTable and thus no lookup occurs.
It immediately calls the derived one instead of having to decide whether the user meant derived or base's function. Some languages use a dispatch method to decide which to call. Usually lookup occurs when trying to decide which function to call from a base pointer to a derived instance.. Anyway, enough rambling..
If we do NOT overload the function, then we must decide for ourselves which one to call.. We do this manually. Now we know that the derived class inherits from the base class and so they shared the same memory address! Using this and the fact that we can cast (dynamic_cast) one to the other, we can cast a pointer to derived to a pointer to base and call the function through that..
Solution:
type
T3DPoint = record
X, Y, Z : Extended;
end;
T3DColorPoint = record(T3DPoint)
color : Integer;
end;
procedure T3DPoint.create(pX, pY, pZ : Extended);
begin
self.X := pX;
self.Y := pY;
self.Z := pZ;
end;
procedure T3DColorPoint.create(pX, pY, pZ : Extended; pColor : Integer);
type TP = ^T3DPoint;
begin
TP(@self)^.create(pX, pY, pZ); //Cast a pointer to "self (derived)" to a pointer to "base" and call 'create' through the "base" pointer.
//In C++, this function would be an overload and virtual and thus a lookup would occur due to calling create through the base pointer.
//That's basically what I was trying to explain in that long paragraph above..
self.color := pColor;
end;
var
P : T3DPoint;
cP : T3DColorPoint;
begin
P.create(1.0, 2.0, 3.0);
cP.create(3.0, 5.0, 7.0, 9);
writeLn(P, ' ', cP);
end;
Voila for workarounds.. This is NOT a hack. It's a very good "trick" with good solid proof.. It is usually done in C++ (automatically or manually). I never thought I'd see it in Lape.. Seeing as lape has pointers and stuff, you might be seeing a lot of C and C++ techniques leak into lape.
NOTE: Don't cast or assign derived to base directly. It must be a pointer (all pointers are the same size). If you do it directly without pointers, derived is larger than base and you may actually introduce a problem known as slicing:
http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c