2013/9/29 Sven Barth
Show quoted text 6 lines
If you want to override the virtual Clone method of TTree<LongInt> in
TIntTree you need to use the same result type + override or otherwise you
gain nothing, because the compiler will not consider the method as
overloaded and use the Clone method of TTree<LongInt> inside
TTree<LongInt>'s methods instead.
Yes, you are right, for virtual method, you need have exactly same type... But this leads me to think how the generics are implemented? For example:
=== snippet 1 ===
type
TIntTree = class(specialize TTree<Integer>)
public
function Clone: TTree; override;
end;
=== end of snippet 1 ===
This will leads to a compile error: Generics without specialization cannot be used as a type for a variable.
If so, why in the code TTree can be used everywhere, for example:
=== snippet 2 ===
function TTree.Level: Cardinal;
var
n: TTree; <-- here TTree is not specialized.
begin
... ...
end;
=== end of snippet 2 ===
In snippet 1, why the compiler don't treat the TTree same as its own type i.e. TIntTree? I imagine that TTree in snippet 1 is logically similar to TObject. I mean, a class's method is of course possible to return a value of its parent's type or any other class's instance?
Would you please show how exactly you changed the code? With all those
methods calling each other it's a bit hard to imagine in my head what you
changed. ;)
With your TSelfClass solution in TTree, I mean either:
=== solution 1 ===
type
TIntTree = class(specialize TTree<Integer>
public
function Clone: TIntTree;
end;
function TIntTree.Clone: TIntTree;
begin
Result := TIntTree(inherited Clone); //typecast in TIntTree
end;
=== end of solution 1===
or:
=== solution 2 ===
type
TIntTree = class(specialize TTree<Integer>)
end;
begin //main
it2 := TIntTree(it1.Clone); //typecast in main program
end.
=== end of solution 2 ===
Are both solutions correct?
Regards,
Xiangrong