Examples Delphi

Title: When should I use Virtual methods in my class?
If you've delved into the VCL source code, you would have seen things like this (taken from the interface section of TWinControl):
CODE
procedure
DefineProperties(Filer: TFiler);
override
;
procedure
DestroyHandle;
procedure
DestroyWindowHandle;
virtual
;
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
type
TBase =
class

public

procedure
MyVirtualMethod;
virtual
;

procedure
MyStaticMethod;

procedure
ShuntVirtual;

procedure
ShuntStatic;

end
;
TDescendent = class(TBase)

public

procedure
MyVirtualMethod;
override
;

procedure
MyStaticMethod;

end
;
implementation
// snip
procedure
TBase.ShuntVirtual;
begin
MyVirtualMethod;
end
;
procedure
TBase.ShuntStatic;
begin
MyStaticMethod;
end
;
Ignoring the ShuntXXX methods for the moment, if you declare an object eg.
CODE
var
o : TDescendent;
begin
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
var
Counter : Integer;
o : TDescendent;
{ TBase }
procedure
TBase.MyVirtualMethod;
begin
Counter := Counter +
1
;
end
;
procedure
TBase.MyStaticMethod;
begin
Counter := Counter +
1
;
end
;
{ TDescendent }
procedure
TDescendent.MyVirtualMethod;
begin

inherited
;
Counter := Counter +
2
;
end
;
procedure
TDescendent.MyStaticMethod;
begin

inherited
;
Counter := Counter +
2
;
end
;
begin
o := TDescendent.Create;
Counter :=
0
;
o.MyVirtualMethod;
// Counter = 3
o.MyStaticMethod;
// Counter = 6
o.ShuntVirtual;
// Counter = 9
o.ShuntStatic;
// Counter = 10
end
;