Overriding Functions in a Derived Class


In the last section, we described hiding methods. But developers often want to be able to override methods from the base class. For example, in a banking application, let's say a developer defines a class called Account with a method called MakeDeposit. The author of the class writes a default implementation of the MakeDeposit method. Later a developer creates a class called Checking that inherits the methods from the Account class, but the MakeDeposit method needs to work differently. What's more, the same developer creates a Savings class and the Savings class would also like to have a different version of MakeDeposit. For this reason the author of Account may decide to make the MakeDeposit function virtual.

To override functions from a base class:

  1. The developer of the base class must first grant permission to override a function. To do this type virtual after the access modifier of the function and before the function's return type ( Figure 5.24 ).

  2. In the derived class, enter a function declaration that is identical to the function you want to override.

  3. Type override after the function access modifier and before the function's return type ( Figure 5.25 ).

Figure 5.24 To enable programmers to override the code in a function, you have to mark the function as virtual.
 class Account {   protected decimal m_balance = 0.0m;   // default implementation of   // MakeDeposit   public  virtual  void MakeDeposit(decimal                                   amount)   {      m_balance +=amount;   } } 
Figure 5.25 To override a virtual function you have to use the override keyword; otherwise the compiler will use the hiding mechanism as described earlier.
 class Checking : Account {    // specialized Checking implementation    // of MakeDeposit    public  override  void MakeDeposit(                   decimal amount)    {       if (amount > 500.0m)             m_balance +=amount;       else          // do some validation first          if (ValidateDeposit())             m_balance +=amount;          else             throw new             InvalidOperationException();    }    public bool ValidateDeposit()    {       //include some checking account       // validation       return true;    } } 

graphics/tick.gif Tips

  • The virtual function mechanism is used for polymorphism ( Figure 5.26 ). Notice from the example that the PrintBalance function accepts any class that derives from Account, however, the implementation of PrintBalance in both Checking and Savings differs . Polymorphism means that the execution of a function may be different depending what object you send to the function.

    Figure 5.26 Notice that the DepositMoney function has a parameter of type Account. With polymorphism we can pass to this function either a Checking object or a Savings object and the function will call MakeDeposit in the corresponding class.
     class Account {   protected decimal m_balance = 0.0m;   public virtual void MakeDeposit(                      decimal amount)   {     m_balance +=amount;   } } class Checking : Account {  public override void MakeDeposit(   decimal amount)  {     // specialized Checking     // implementation of MakeDeposit   } } class Savings : Account {  public override void MakeDeposit(   decimal amount)  {      // specialized Savings      // implementation of MakeDeposit   } } class Bank {    static void CreateAccount()    {       Savings s = new Savings();  DepositMoney  (s);       Checking c = new Checking();  DepositMoney  (c);    }    // Can pass in anything that "IS A"    // Account    static void DepositMoney(  Account  acct)    {      acct.MakeDeposit(1000.0m);    } } 
  • When you use virtual functions and make a method call, the method to be executed depends on the type of object that you create, not on the type of variable pointing to the object ( Figure 5.27 ).

    Figure 5.27 Even though the variable in DepositMoney is of type Account because we are passing an object of type Savings and because Savings is overriding MakeDeposit, the code will execute the version of MakeDeposit in Savings.
     class Account {   protected decimal m_balance = 0.0m;  public virtual void MakeDeposit(   decimal amount)  {     m_balance +=amount;   } } class Savings : Account {  public override void MakeDeposit(   decimal amount)  {      // specialized Savings      // implementation of MakeDeposit   } } class Bank {   static void CreateAccount()   {      Savings s = new Savings();      DepositMoney(s);   }   static void DepositMoney(Account acct)   {  //Even though the variable is of   // type Account the call to   // MakeDeposit calls the overridden   // method in Savings  acct.  MakeDeposit  (1000.0m);   } } 
  • Even code within the base class that calls the function will execute the version in the derived class if the code created an instance of the derived type ( Figure 5.28 ).

    Figure 5.28 The code in Bank creates a Savings object, then calls the DoBanking method. DoBanking is part of Account not Savings. This is legal, because Savings derives from Account. However, when DoBanking calls MakeDeposit the code executes the version in Savings because the object type is really Savings.
     class Account {   protected decimal m_balance = 0.0m;   // default implementation of   // MakeDeposit   public virtual void MakeDeposit(                      decimal amount)   {      m_balance +=amount;   }   public void DoBanking()   {  // This will call the Savings version   // of MakeDeposit  this.  MakeDeposit  (200.0m);   } } class Savings : Account {  public override void MakeDeposit(   decimal amount)  {     // specialized Savings implementation     // of MakeDeposit   } } class Bank {   statis void CreateAccout()   {     Account s = new Saving();  s.DoBanking();  } } 
  • A class author may choose to override a function in the base class but may want to invoke some of the default functionality in the original method ( Figure 5.29 ).

    Figure 5.29 You can call a method in your base class by using the base keyword.
     class Checking : Account {    public override void MakeDeposit(                        decimal amount)    {       // specialized Checking       // implementation of MakeDeposit       // after specialized code, call       // base class's version  base  .MakeDeposit(amount);    } } 



C#
C# & VB.NET Conversion Pocket Reference
ISBN: 0596003196
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Jose Mojica

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