2014-02-26 132 views
8

我有一個困惑,我想解決..在C#中,只有具有virtual標記的基類方法可以在派生類中重寫。不包含virtual標記的基類方法不能被覆蓋。充其量,派生類可以使用new隱藏基類方法。然後我們有sealed方法,這些方法也不能在基類中重寫。非虛擬方法和密封方法有什麼區別?

那麼,密封的方法和標準的非虛擬方法有什麼區別呢?

另一個相關的問題。可以使用new在派生類中替換基類sealed方法嗎?

+0

密封和虛擬關鍵字不服務於相同的目的。可以在虛擬方法上定義密封方法 – Aidin

+0

最後一個問題:'new'修飾符不能代替任何東西。它只是告訴編譯器停止抱怨,當你在你的類中引入一個** new **成員與已存在的(繼承)成員具有相同的名稱(加上方法的簽名)時,會停止抱怨。沒有什麼被取代。這兩種方法(成員)都在那裏,但不相關。在某些情況下,其中一種方法是** hidden **,但仍可通過將引用強制轉換爲基本類型來找到(並調用)該方法。避免使用'new'修飾符;相反,爲新方法選擇一個未使用的名稱。 –

回答

12

sealed阻止任何進一步覆蓋鏈上的虛擬方法。您只能在過期的方法上定義sealed。看看該文檔爲sealedhttp://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx

他們給封閉使用的一個很好的例子:

using System; 
class A 
{ 
    public virtual void F() { 
     Console.WriteLine("A.F"); 
    } 
    public virtual void G() { 
     Console.WriteLine("A.G"); 
    } 
} 
class B: A 
{ 
    sealed override public void F() { 
     Console.WriteLine("B.F"); 
    } 
    override public void G() { 
     Console.WriteLine("B.G"); 
    } 
} 
class C: B 
{ 
    override public void G() { 
     Console.WriteLine("C.G"); 
    } 
} 

在這種情況下,任何人誰導出過的B可以覆蓋G,但不F

+2

嗯..這是C#規範中「密封」的例子。但是非虛方法和區別的解釋在哪裏? –

+0

因此'''封閉',使'虛擬'功能,'非虛擬',在某處下線?我的意思是說,'密封'刪除了方法的'虛擬'分類? – Ahmad

+0

@Ahmad'sealed'表示此方法上次被覆蓋,如果派生,則不能再覆蓋它。 – 2014-02-26 15:51:09

1

如果我正確閱讀this,密封允許虛擬化爲虛擬虛擬。實質上取消了虛擬。

+0

這是不正確的。該方法仍然是虛擬的,只有在方法被「密封」之前,vtable纔會僅限於那些條目。這是一個重要的區別。 – Servy

+1

@Servy,這正是我的意思。將虛擬方法標記爲「密封」的繼承鏈的類基本上阻止那些將方法視爲虛擬(即使原來是虛擬方法)的類繼承它。換句話說,密封的關鍵字會刪除較早的虛擬關鍵字(在該層次上,而不是在下面的層次上,只能在該層次或更高層次上)。 – LB2

2

密封方法只能是從基類重寫方法的方法,因此不可能進一步重載。

從文檔:

當一個實例方法的聲明包括一個密封的改性劑,該方法 被說成是一個密封的方法。
如果一個實例方法 聲明包含密封修飾符,則它還必須包含覆蓋修飾符 。

這不是虛擬方法所必需的。

相關問題