hijacking a class's members
Mafi
mafi at example.org
Wed Aug 4 09:39:19 PDT 2010
> Thats what feels weird to me. a.x can result in different things happening
> even though x exists in both A and the generated class. However the
> generated class has two "fields" called x one you can't access anymore and
> the @property one.
> When I create an instance of the generated class I would expect it to always
> to the same thing if I use one of its methods/properties/etc...
> Kind of like you would expect the following to print out "hello 2":
> class A {
> string toString() { return "hello"; }
> }
> class B : A {
> string toString() { return super.toString() ~ " 2"; }
> }
> void main() {
> A a = new B();
> writeln(a.toString()); // uses B.toString()
> }
>
> What I've got is:
> class A {
> int x;
> }
> class B : A {
> int x() { throw new Exception(); }
> }
> void main() {
> A a = new B();
> writeln(a.x); // this accesses A.x not B.x!!!!
> }
>
> just seems like properties are not quite right or something.
>
> -Rory
>
If you want that to work, both x have to be virtual (ie dynamically
bound). In D all non-final non-ststic clsss-methods are virtual(1).
Consider the following:
///////
class A {
int x = 0;
int getX() { //<-- it's virtual
return x;
}
}
class B : A{
int x = 5;
override int getX() { //<-- it's virtual too
return x;
}
}
void thinAboutA(A a) {
/* Now a call to a non virtual method
* which results in vtbl lookup. a's vtbl
* contains B.getX().
writeln(a.getX());
/* Non virtual field.
* Has to be statically bound
* to a lookup in A.x
*/
writeln(a.x);
}
void main() {
thinkAboutA(new B);
}
////////
Fields have to be statically bound bcause the compiler doesn't enforce
covariance with fields. So you can:
///////////////
class C : A {
string x = "";
}
void main() {
thinkAboutA(new C); //Should evrything crash now? I won't.
}
//////////////
1) I'm not sure about @propertys.
More information about the Digitalmars-d-learn
mailing list