Mega Code Archive

 
Categories / Delphi / Examples
 

When should I use Virtual methods in my class

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 ;