簡體   English   中英

防止在C#中重寫方法

[英]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修飾符指定可以覆蓋方法。 省略它意味着該方法是“最終的”。

具體來說,方法必須是virtualabstractoverride才能被覆蓋。

使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM