2011-10-31 72 views
1

我一直在用C++編程一段時間,現在我開始使用C#,但是我無法得到關於virtualoverride關鍵字的想法。既然指針和所有與它相關的東西大部分都是從C++中刪除的,我們並不真的需要它們嗎?或者我錯過了C#編程的一些主要觀點。C#繼承 - 爲什麼使用覆蓋和虛擬?

例子:

namespace ConsoleApplication1 
{ 
    public class Employee 
    { 
     public virtual void GetPayCheck() 
     { 
      Console.WriteLine("employee gets his pay check "); 
     } 

     public void Work() 
     { 
      Console.WriteLine("employee works "); 
     } 
    } 
    public class Manager : Employee 
    { 
     public override void GetPayCheck() 
     { 
      Console.WriteLine("MANAGER gets his pay check "); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Employee emp = new Employee(); 
      Manager exec = new Manager(); 
      emp.Work(); 
      exec.Work(); 
      emp.GetPayCheck(); 
      exec.GetPayCheck(); 
     } 
    } 
} 

即使我省略虛擬或覆蓋關鍵字(或兩者)我仍然得到同樣的輸出。 我在做什麼

+2

你實際上並沒有做多態。 –

回答

6

使用virtualoverride可以完全替換Work方法,而不管變量聲明爲什麼類型。如果一個方法被聲明爲虛擬的,CLR將檢查該對象是否是派生類,以及方法是否已被覆蓋。如果某個方法不是虛擬的,則CLR只會從該對象聲明爲的類型調用名稱爲Work的方法。

static void Main(string[] args) 
    { 
     Employee emp = new Employee(); 
     Manager exec = new Manager(); 

     DoWork(emp); // employee works and gets pay check 
     DoWork(exec); // if virtual and override are used, MANAGER get pay check 
         // however, if you don't override the method, DoWork 
         // will treat the argument as an Employee. 
    } 

    static void DoWork(Employee emp) 
    { 
     emp.Work(); 
     emp.GetPayCheck(); 
    } 
2

儘管指針語法不見了,但您用C++指針和引用變量學習的概念仍然存在。虛擬在C#中的功能與C++中的功能相同:它將一種方法聲明爲可在子類中進行替換的方法。覆蓋會替換方法是否是虛擬的,所以這就是爲什麼你的代碼按照它的方式工作。

1

嘗試:

Employee manager = new Manager(); 
manager.GetPayCheck(); 

你仍然得到同樣的結果,無論採用哪種方式?

答:你沒有。

如果使用virtualoverride,則ManagerGetPayCheck()版本會被調用,無論如何。如果您省略了virtualoverride,則EmployeeGetPayCheck()版本將在您的實例被轉換爲Employee時得到調用,如果您的實例轉換爲Manager,則會調用Manager的版本。後一種情況稱爲「隱藏」,您將得到一個編譯器警告,建議您使用new關鍵字來明確隱藏是有意的。