2011-11-20 11 views
1

根據我的理解,virtual關鍵字允許您使用基類的方法,並且override允許您在從基類繼承的類中覆蓋它。我的困惑是,我只是在基類的方法定義中沒有使用virtual關鍵字進行測試,並且沒有在派生類中包含該方法,而且我仍然可以調用基類的方法(它在intellisense中顯示並運行) 。此外,我知道,如果我想爲我的派生類,我可以使用新的關鍵字相同的方法定義一個新的方法。虛擬和覆蓋是什麼?不是C#沒有它們做同樣的事情嗎?

我可能缺少一個關鍵點,但這是我明白它的方式是爲什麼我對虛擬和覆蓋的目的感到困惑

+0

的可能重複的[C#關鍵字的使用虛擬+重寫與新(http://stackoverflow.com/questions/159978/c-sharp -keyword-usage-virtualoverride-vs-new) – BrokenGlass

回答

2

我的困惑的是,我只是測試不使用虛擬關鍵字 基類的方法的定義和不包括在 派生類的方法,和我仍然能夠調用基類的方法(它在intellisense中出現並跑了)。

這是預期的行爲。

Virtual允許您在這個基類中定義的方法,換句話說就是擴展派生類中方法的實現。

新關鍵字與覆蓋之間的差異can be found on MSDN here

這是access modifiers(私人,公共,受保護),如果您能夠調用派生類中的基類方法,將會產生影響。

+0

這不就是「新」關鍵字的作用嗎?我剛剛測試了它,它在我使用「new」關鍵字時從我的派生類運行了該方法(是否與重寫相同?) – bruchowski

+0

添加了MSDN文章的鏈接,該文章解釋了override和new之間的區別。 –

+0

感謝羅賓,MSDN文章解釋了一切,非常感謝 – bruchowski

0

虛擬允許你重寫基類的方法。您仍然可以調用沒有它的方法,但是如果沒有它,將無法重寫該方法。

對不起,我忘了提及多態。所以,如果你有一個定義方法的基類,你可以這樣做。

以下代碼段將從乙

public class A 
{ 
    virtual void foo 
    { 
    Console.WriteLine("From A"); 
    } 
} 

public class B : A 
{ 
    override void foo() 
    { 
    Console.WriteLine("From B"); 
    } 
} 

static void Main(string[] args) 
{ 
    A testA = new B(); 

    a.foo(); 
} 
+0

這不就是「新」關鍵字的作用嗎?當我使用「new」關鍵字 – bruchowski

+0

@ Maximus9000時,我剛剛對它進行了測試,並從我的派生類中運行該方法:此處的重要概念是[多態性](http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming) – knittl

0
打印

要覆蓋在基類要覆蓋的方法必須被標記爲虛擬的方法 - 重寫使用覆蓋鍵字的方法。

新方法中的上下文略有不同。它允許您在子類中添加一個名稱與基類中的方法相同的方法。調用哪個方法將取決於您用於訪問方法的引用。

您可以訪問基類中實現的任何方法(受訪問修飾符限制),而不管它們是否標記爲虛擬。

+0

因此,實質上,您可以使用'new'關鍵字來有效地覆蓋基類的方法,那麼使用virtual和override會更合適嗎? – bruchowski

+0

當使用new時,你並不是重寫,你只是添加另一個方法,它恰好與基類中的方法具有相同的名稱。 – s1mm0t

0

將方法標記爲虛擬或抽象時,將使用運行時類型檢查來確定要調用的方法的實際實現:它會檢查實現/覆蓋虛擬方法的「最大派生類型」,以及調用該實現。普通方法不需要運行時類型檢查。

因此,虛擬和非虛擬之間的區別對代碼的語義有特殊的影響,特別是對於公共API。如果你看到這一點:

class A { void foo(); virtual void bar(); } 
... 
A myObject = getSomeObject(); 
myObject.foo(); 
myObject.bar(); 

您可以確信的foo被調用的實現是一個在A類中聲明。這是因爲只使用編譯時類型檢查來確定要調用的方法。但是,調用bar的具體實現可能是A的某些子類中的實現,具體取決於myObject的運行時類型。

更多信息:http://msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx

3

這些關鍵字的力量開始發揮作用,當您使用polymorphism

我想到一個例子有助於理解最。考慮以下幾點:

class Base { 
    public virtual void f() { Console.WriteLine("Virtual Base"); } 
} 

class Override : Base { 
    public override void f() { Console.WriteLine("Overridden derived"); } 
} 

class New : Base { 
    public new void f() { Console.WriteLine("New derived"); } 
} 

現在,當你有實際類型Derived但靜態類型Base的對象,調用f()仍將輸出「重寫派生」:

Base obj = new Override(); 
obj.f(); // Overridden derived 

隨着new關鍵字你告訴運行時停止尋找具有該類名稱的方法:

Base obj = new New(); 
obj.f(); // Virtual Base 

相反的類型的主叫f()至少New

New obj = new New(); 
obj.f(); // New derived 
相關問題