Method hiding

   


Even if a function member (here referring to a method, property or indexer) is not declared virtual in a base class you can still write a function with the same signature and return type in its derived class. However, the dynamic binding mechanism will never be activated for this function. Consequently if you call a non-virtual function for a variable of a base class which references an object of the derived type it will invoke the version implemented in the base class not the version implemented in the derived class (as had been the case if the function was declared virtual). Instead of overriding the non-virtual base class function the new function is said to hide the base class function. Listing 17.9 demonstrates the difference between overriding and hiding a base class method.

Listing 17.9 Source code of MethodHidingTest.cs
01: using System; 02: 03: class Car 04: { 05:     public virtual void MoveForward() 06:     { 07:         Console.WriteLine("Move Car forward by 1 kilometer"); 08:     } 09: 10:     public void Reverse() 11:     { 12:         Console.WriteLine("Reverse Car by 50 meters"); 13:     } 14: } 15: 16: class FamilyCar : Car 17: { 18:     public override void MoveForward() 19:     { 20:         Console.WriteLine("Move Family Car forward by 5 kilometers"); 21:     } 22: 23:     public new void Reverse() 24:     { 25:         Console.WriteLine("Reverse the Family Car by 200 meters"); 26:     } 27: } 28: 29: class Tester 30: { 31:     public static void Main() 32:     { 33:         Car myCar; 34: 35:         myCar = new FamilyCar(); 36:         myCar.MoveForward(); 37:         myCar.Reverse(); 38:     } 39: } Move Family Car forward by 5 kilometers Reverse Car by 50 meters 

To demonstrate the difference between a virtual and a non-virtual method the Car class is equipped with one of each kind. The virtual method MoveForward and the non-virtual method Reverse. The FamilyCar class is derived from Car. It overrides the MoveForward method in lines 18-21 and hides the Reverse method in lines 23-26.

Whenever you hide a function you should include the keyword new as in line 23 (which in this context has a different meaning than the keyword new that we use to instantiate new objects). We will return to the new keyword in a moment. For now simply regard it as necessary to keep the compiler from generating a warning.

In usual fashion we declare a variable of the base class Car in line 33 and assigns it a reference to an object of its derived class FamilyCar in line 35. As the output confirms dynamic binding is activated (in line 36) for the virtual MoveForward method resulting in the execution of the implementation residing in the derived class FamilyCar. In contrast dynamic binding is not applied (in line 37) to the non-virtual method Reverse resulting in the Reverse implementation residing in myCar's type Car to be executed. So no matter which type of object myCar is referencing this call:

 myCar.Reverse() 

will always cause the Reverse implementation found in the Car class to be executed because myCar is of type Car. This causes a serious problem. If myCar is referencing an object of a derived class we clearly want the derived class implementation of Reverse to be executed. To resolve this problem the Reverse method should be declared virtual like MoveForward.

Most of the functions declared for a base class are analogous to the MoveForward and Reverse methods in that they need to be declared virtual to avoid the kind of problems experienced with the non-virtual method Reverse in Listing 17.9. If virtual functions are much more common than non-virtual functions why does a function (without the virtual keyword) then default to become a non-virtual method? One of the main reasons has to do with a concept called versioning presented in the next section.


   


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net