2014-11-05 65 views
1

我只是有一個基本的問題:函數重載和覆蓋

public class virtualTest 
    { 
     public virtual void vTest() 
     { 
      Console.WriteLine("Base Class"); 
     } 
    } 

    public class derivedVirtualTest : virtualTest 
    { 
     public override void vTest() 
     { 
      Console.WriteLine("Derived Class"); 
     } 
    } 

在這裏,我已經使用功能與功能VTEST()

重寫但是,如果我:

public class virtualTest 
    { 
     public void vTest() 
     { 
      Console.WriteLine("Base Class"); 
     } 
    } 

    public class derivedVirtualTest : virtualTest 
    { 
     public void vTest() 
     { 
      Console.WriteLine("Derived Class"); 
     } 
    } 

中移除了虛擬和覆蓋各個地方的關鍵字,然後還有代碼作品。

這怎麼可能?

或者如果代碼工作正常,沒有虛擬和重寫,那麼override和virtual(整個函數覆蓋)的用法是什麼?

編輯:

我的方法,通過它我打電話上述類

static void Main(string[] args) 
     { 



      derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest(); 
      objderivedVirtualTest.vTest(); 

      virtualTest objvirtualTest = new virtualTest(); 
      objvirtualTest.vTest(); 

      Console.ReadLine(); 


     } 
+0

你說這段代碼有效,但你從來沒有顯示過你如何測試它。也發佈該代碼。這是最重要的部分。 – 2014-11-05 06:45:19

+0

@SriramSakthivel剛剛發佈。請看看它 – 2014-11-05 06:48:10

+0

請參考[this](http://stackoverflow.com/questions/392721/difference-between-shadowing-and-overriding-in-c)要使用多態,你需要編譯時間類型爲basetype不是派生類型。只需將'derivedVirtualTest objderivedVirtualTest'更改爲'virtualTest objderivedVirtualTest'來查看差異。 – 2014-11-05 07:00:00

回答

2

正如qwr所解釋的,mai在OOP方面的差異是多態性。這意味着如果您通過基本類型引用訪問基類成員覆蓋的類,則您對可重寫成員執行的調用將被重定向到覆蓋。

如果是基類成員,則調用不會被重定向,並且基類的方法正在執行,如果類別爲陰影/隱藏

因此,考慮到:

class Base 
{ 
    public virtual void OverrideMe() 
    { 
     Console.WriteLine("I'm the base"); 
    } 
} 

class Derived : Base 
{ 
    public override void OverrideMe() 
    { 
     Console.WriteLine("I'm derived"); 
    } 
} 

class Shadowing : Base 
{ 
    public void OverrideMe() 
    { 
     Console.WriteLine("I'm shadowing"); 
    } 
} 

並利用他們這樣說:

var instances = new Base[] {new Base(), new Derived(), new Shadowing()}; 

foreach (var instance in instances) 
{ 
    instance.OverrideMe(); 
} 

會產生:

我來源的基本

我是基地

另外的區別在於,如果重寫可以演變您的基類,例如更改基礎成員的簽名或完全刪除它,而不更改隱藏基類。在某些情況下,這可能恰恰適合需要,而在某些情況下可能不太適合。

如果覆蓋你,必須也改變覆蓋成員的簽名,否則你的代碼將無法編譯。

+0

假設在上面的例子中只有兩個類:Base和Shadowing,OverrideMe在Base中沒有聲明爲虛擬。那是不是叫做陰影? – 2014-11-05 07:20:14

+1

是的。如果通過* Base *類型引用派生類,派生方法將永遠不會被調用。另外,你甚至可以讓隱藏方法返回一些值(而不是* void *),編譯器不會產生錯誤,只警告不使用* new *關鍵字。 – galenus 2014-11-05 07:32:57

+0

謝謝老闆:) – 2014-11-05 07:35:15

5

在第一次就可以實現polimorphism。第二你不能。

首先叫overriding,第二個叫hiddingshadowing (Vb.Net)

而且還有問一下這麼多的問題。

override vs hiding questions

Differences Between Shadowing and Overriding MSDN

+0

但是這裏寫的是:請注意,在C#中,你不能覆蓋非虛擬或靜態方法。但是我沒有虛擬的方法overrided – 2014-11-05 06:50:48

+0

你是什麼意思?第二你不能做多態嗎? @qwr – dotctor 2014-11-05 06:53:01

+0

我只是說如果你把派生類當作基類並調用它的函數,它會調用基類函數。 – qwr 2014-11-05 06:58:51

1

在第二個例子,也許你測試你的代碼是這樣的:

derivedVirtualTest deviTest = new derivedVirtualTest(); 
deviTest.vTest(); //Result "Derived Class" 

試試這個,你會看到該函數has't被覆蓋還有:

virtualTest deviTest = new derivedVirtualTest(); 
deviTest.vTest(); //Result "Base Class" 
//This will result "Dervived class" in the first one