If you've delved into the VCL source code, you would have seen things like this (taken from the interface section of TWinControl):
Code:
[b]procedure[/b] DefineProperties(Filer: TFiler); [b]override[/b];
[b]procedure[/b] DestroyHandle;
[b]procedure[/b] DestroyWindowHandle; [b]virtual[/b];
I was always confused about the difference between overriding a
static method (DestroyHandle), and overriding a
virtual method (DestroyWindowHandle). When you're overriding a virtual method, the descendent method must use the reserved word
override after the method declaration in the interface section, but you don't when overriding a static method. What's the difference in functionality? I finally took the time to test it all out.
Take the following classes:
Code:
[b]type[/b]
TBase = [b]class[/b]
[b]public[/b]
[b]procedure[/b] MyVirtualMethod; [b]virtual[/b];
[b]procedure[/b] MyStaticMethod;
[b]procedure[/b] ShuntVirtual;
[b]procedure[/b] ShuntStatic;
[b]end[/b];
TDescendent = class(TBase)
[b]public[/b]
[b]procedure[/b] MyVirtualMethod; [b]override[/b];
[b]procedure[/b] MyStaticMethod;
[b]end[/b];
[b]implementation[/b]
[navy]// snip[/navy]
[b]procedure[/b] TBase.ShuntVirtual;
[b]begin[/b]
MyVirtualMethod;
[b]end[/b];
[b]procedure[/b] TBase.ShuntStatic;
[b]begin[/b]
MyStaticMethod;
[b]end[/b];
Ignoring the ShuntXXX methods for the moment, if you declare an object eg.
Code:
[b]var[/b]
o : TDescendent;
[b]begin[/b]
o := TDescendent.Create;
If you call either o.MyVirtualMethod or o.MyStaticMethod, both will call the method in TDescendent.
If you call ShuntVirtual, it's reference to MyVirtualMethod will call TDescendent.MyVirtualMethod.
However, if you call ShuntStatic, it's reference to MyStaticMethod will call
TBase.MyStaticMethod.
Here's some code examples to make all that clear - here's the implementation of the other methods:
Code:
[b]var[/b]
Counter : Integer;
o : TDescendent;
[navy]{ TBase }[/navy]
[b]procedure[/b] TBase.MyVirtualMethod;
[b]begin[/b]
Counter := Counter + [purple]1[/purple];
[b]end[/b];
[b]procedure[/b] TBase.MyStaticMethod;
[b]begin[/b]
Counter := Counter + [purple]1[/purple];
[b]end[/b];
[navy]{ TDescendent }[/navy]
[b]procedure[/b] TDescendent.MyVirtualMethod;
[b]begin[/b]
[b]inherited[/b];
Counter := Counter + [purple]2[/purple];
[b]end[/b];
[b]procedure[/b] TDescendent.MyStaticMethod;
[b]begin[/b]
[b]inherited[/b];
Counter := Counter + [purple]2[/purple];
[b]end[/b];
[b]begin[/b]
o := TDescendent.Create;
Counter := [purple]0[/purple];
o.MyVirtualMethod; [navy]// Counter = 3 [/navy]
o.MyStaticMethod; [navy]// Counter = 6 [/navy]
o.ShuntVirtual; [navy]// Counter = 9 [/navy]
o.ShuntStatic; [navy]// Counter = 10 [/navy]
[b]end[/b];