متدهای مجازی

متدهای مجازی متدهایی از کلاس پایه هستند که می‌توان به وسیله یک متد از کلاس مشتق آنها را override کرده و به صورت دلخواه پیاده سازی نمود.

به عنوان مثال شما متد A را در کلاس A دارید و کلاس B از کلاس A ارث بری می‌کند، در این صورت متد A در کلاس B در دسترس خواهد بود. اما متد A دقیق همان متدی است که از کلاس A به ارث برده شده است. حال اگر بخواهید که این متد رفتار متفاوتی از خود نشان دهد چکار می‌کنید؟ متد مجازی این مشکل را برطرف می‌کند. به تکه کد زیر توجه کنید.

   1: using System;                                     
   2:                                                   
   3: class Parent                                      
   4: {                                                 
   5:     public virtual void ShowMessage()             
   6:     {                                             
   7:         Console.WriteLine("Message from Parent.");
   8:     }                                             
   9: }                                                 
  10:                                                   
  11: class Child : Parent                              
  12: {                                                 
  13:     public override void ShowMessage()            
  14:     {                                             
  15:         Console.WriteLine("Message from Child."); 
  16:     }                                             
  17: }                                                 
  18:                                                   
  19: class Program                                     
  20: {                                                 
  21:     public static void Main()                     
  22:     {                                             
  23:         Parent myParent = new Parent();           
  24:         Child myChild = new Child();              
  25:                                                   
  26:         myParent.ShowMessage();                   
  27:         myChild.ShowMessage();                    
  28:     }                                             
  29: }
Message from Parent.
Message from Child.

متد مجازی با قرار دادن کلمه کلیدی virtual هنگام تعریف متد، تعریف می‌شود. (خط 5) این کلمه کلیدی نشان می‌دهد که متد می‌تواند override شود یا به عبارت دیگر می‌تواند به صورت دیگر پیاده سازی شود. کلاسی که از کلاس Parent ارث می‌برد شامل متدی است که متد مجازی کلاس پایه را override یا به صورت دیگری پیاده سازی می‌کند. با استفاده از کلمه کلیدی override می‌توان متد مجازی کلاس پایه را به صورت دیگر پیاده سازی کرد. با استفاده از کلمه کلیدی base (خط 17) می‌توانید متد مجازی را در داخل متد override شده فراخوانی کنید.

   1: using System;
   2: 
   3: class Parent
   4: {
   5:     private string name = "Parent";
   6:     
   7:     public virtual void ShowMessage()
   8:     {
   9:         Console.WriteLine("Message from Parent.");
  10:     }
  11: }
  12: 
  13: class Child : Parent
  14: {
  15:     public override void ShowMessage()
  16:     {
  17:         base.ShowMessage();
  18:         Console.WriteLine("Message from Child.");
  19:     }
  20: }
  21: 
  22: class Program
  23: {
  24:     public static void Main()
  25:     {
  26:         Parent myParent = new Parent();
  27:         Child myChild = new Child();
  28: 
  29:         myParent.ShowMessage();
  30:         myChild.ShowMessage();
  31:     }
  32: }
Message from Parent.
Message from Parent.
Message from Child.

اگر بخواهید از متد پایه استفاده کنید و هیچ کدی داخل متد override نباشد (مثلاً فرض کنید خط 18 در مثال بالا وجود نداشته باشد)، بسیار شبیه به این است که از هیچ متد override ی استفاده نکرده‌اید.

  • نمی‌توان متد غیر virtual و یا یک متد static را override کرد.
  • متد override نیز باید دارای سطح دسترسی شبیه به متد مجازی باشد.

می‌توان یک کلاس دیگر که از کلاس Child ارث بری می‌کند ایجاد کرده و دوباره متد ShowMessage() را override کرده و آنرا به صورت دیگر پیاده سازی کنیم. اگر بخواهید متدی را که ایجاد کرده‌اید به وسیله سایر کلاسها override نشود کافیست که از کلمه کلیدی sealed به صورت زیر استفاده کنید :

public sealed override void ShowMessage()

حال اگر کلاس دیگری از کلاس Child ارث ببرد نمی‌تواند متد ShowMessage() را override کند. به یک مثال دیگر توجه کنید. فرض کنید می‌خواهیم متد ToString() کلاس System.Object را override کنیم. همانطور که در درس آینده خواهید دید همه کلاسها در سی شارپ از کلاس Object ارث می‌برند.

   1: using System;                                 
   2:                                               
   3: class Person                                  
   4: {                                             
   5:     public string FirstName { get; set; }     
   6:     public string LastName { get; set; }      
   7:                                               
   8:     public override string ToString()         
   9:     {                                         
  10:         return FirstName + " " + LastName;    
  11:     }                                         
  12: }                                             
  13:                                               
  14: class Program                                 
  15: {                                             
  16:     public static void Main()                 
  17:     {                                         
  18:         Person person1 = new Person();        
  19:                                               
  20:         person1.FirstName = "John";           
  21:         person1.LastName = "Smith";           
  22:                                               
  23:         Console.WriteLine(person1.ToString());
  24:     }                                         
  25: }
John Smith

از آنجاییکه متد ToString() کلاس System.Object را override کرده‌ایم، به جای چاپ نوع شیء پیشفرض، خروجی ما سفارشی شده و نام و نام خانوادگی نمایش داده می‌شود.