[英]Preventing a method from being overridden in C#
如何防止在派生類中重寫方法?
在Java中,我可以通過在我希望防止被覆蓋的方法上使用final
修飾符來實現。
我如何在C#中實現同樣的目標?
我知道使用sealed
但顯然我只能使用override
關鍵字?
class A
{
public void methodA()
{
// Code.
}
public virtual void methodB()
{
// Code.
}
}
class B : A
{
sealed override public void methodB()
{
// Code.
}
}
所以在上面的例子中,我可以防止方法methodB()
被從類B
派生的任何類重寫,但是如何防止類B
覆蓋methodB()
?
更新:當我發布此問題時,我在A類的methodB()
聲明中錯過了virtual
關鍵字。 糾正了它。
你不需要做任何事情。 virtual
修飾符指定可以覆蓋方法。 省略它意味着該方法是“最終的”。
具體來說,方法必須是virtual
, abstract
或override
才能被覆蓋。
使用new
關鍵字將允許隱藏基類方法,但它仍然不會覆蓋它,即當您調用A.methodB()
您將獲得基類版本,但如果您調用B.methodB()
您將獲得新版本。
正如您所提到的,您可以通過使用sealed
with override
來防止在B類中進一步覆蓋MethodB
class B : A
{
public sealed override void methodB()
{
Console.WriteLine("Class C cannot override this method now");
}
}
使用sealed
修飾符和 override
阻止派生類進一步覆蓋該方法。
如果您不希望A類中的methodB
被任何子類重寫,請不要將該方法標記為virtual
。 只需刪除它。 virtual關鍵字允許在子類中重寫該方法
public void methodA()
{
}
在類上使用sealed
關鍵字以防止進一步覆蓋類
在C#中,未標記為virtual
的功能(也包括虛擬功能的覆蓋)實際上是密封的,不能被覆蓋。 因此,您的示例代碼實際上不會編譯,因為override關鍵字無效,除非在基類中有一個標記為virtual且具有相同簽名的方法。
如果A.methodB()被標記為虛擬,那么您可以從A覆蓋該方法,但是在使用與您顯示的sealed
關鍵字完全無關的類中,可以防止它進一步被覆蓋。
要記住的一件事是,雖然可以防止方法覆蓋,但方法隱藏不能。 鑒於您目前對A類的定義,B類的以下定義是合法的,您無能為力:
class B:A
{
public new void methodB()
{
//code
}
}
new
關鍵字基本上“中斷”繼承/覆蓋層次結構,因為它與這一方法有關; 任何對B類的引用,被視為B類(或任何進一步派生類型)將使用B類中的實現並忽略A類中的實現,除非B的實現特別回調它。 但是,如果要將類B的實例視為類A(通過強制轉換或將其作為參數傳遞),則忽略“新”實現。
這與覆蓋不同,其中被視為A類並且真正覆蓋虛擬方法B的B類仍將使用B類覆蓋該方法。 還要了解方法隱藏是推斷的(雖然你會得到編譯器警告); 如果在派生類中聲明具有相同簽名的方法並且未指定new或override,則將隱藏基類方法。
在基類中,sealed關鍵字僅用於防止派生類,但在繼承的類中,它可用於防止另一個繼承的類覆蓋該方法。
要防止覆蓋基類方法,只需將其指定為虛擬方法即可。 在您提供的示例中,B類無法覆蓋methodB
因為在原始類上沒有將methodB
標記為虛擬。
這將編譯:
class A
{
public virtual void methodA()
{
//code
}
public virtual void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
這不會:
class A
{
public void methodA()
{
//code
}
public void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
EDITTED:澄清並更正了我關於sealed關鍵字的原始陳述
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.