簡體   English   中英

C #Searled防止派生方法

[英]C# Sealed Prevent a method to be derived

我試圖阻止我的基類派生它的一個方法,但似乎不可能以我喜歡的方式做它,我認為我做錯了。

你能幫幫忙嗎? :)我真的想成功使用密封的關鍵字!

這是一些代碼:

public class BaseClass
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public sealed void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

發生的事情是有問題的,關鍵字密封不允許在第一級推導中的方法。 我只有一個派生級別,我正在尋找的是避免在DerivedClass中派生MyMethod2。

但它似乎沒有問題:/任何建議或更正?

提前致謝 :)

編輯:經過許多評論和午餐暫停后,我會嘗試明確我的問題!

我真正想做的是阻止我的班級使用“她”繼承的方法之一。 有些人提到使用構圖而不是繼承,因為它似乎誤解了它的含義。

我認為組合只存在於UML而不是代碼中。 在C#代碼中聽起來像什么?

如果這是第一級,除非標記為virtualabstract否則它不會被派生類覆蓋。

public class BaseClass
{
    public virtual void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    public override void MyMethod1(string input){..}

    /// MyMethod2 is not overridable
}

根據你下面的評論,你真正想要的似乎是構圖,而不是繼承; 也就是說DerivedClass應該能夠訪問BaseClass上的某些功能,但不應該以任何方式更改它。 對於您的類示例,這可能如下所示。

public class CompositeFunctionality
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
}
public class BaseClass
{
    private CompositeFunctionality composite = new CompositeFunctionality();
    public void MyMethod2(string input)
    {
        // this is accessible in the base class
        composite.MyMethod1();
    }
}

public class DerivedClass : BaseClass
{
    public void MyMethod3(string input)
    {
         // do whatever you want
         // but composite is not accessible here
    }
}

您只能密封覆蓋基類中的虛方法的方法/屬性。 你的MyMethod2不是虛擬的,因此無法密封。 事實上,它不是虛擬的,而是隱含的密封!

您需要另一級別的繼承才能使用sealed 您可以在基類中將方法標記為virtual ,並在第二個類中override sealed它。

你可以創建“絕對基礎”抽象,所以它不可能實例化它,然后繼承它來實現和密封它:

public abstract class VeryBaseClass
{
    public abstract void MyMethod2(string input);
}

public class BaseClass : VeryBaseClass
{
    public override sealed void MyMethod2(string input)
    {

    }
}

public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

但就像@Jenish所說 ,默認情況下C#中的方法是封閉的。

相反,為了能夠覆蓋一個方法,它必須被標記為virtual ,所以你的問題似乎根本不是問題。 只需將MyMethod1標記為virtual即可覆蓋它, MyMethod2將保持非虛擬狀態,因此根本不可覆蓋。

sealed關鍵字隱含在基類中的任何方法中,該方法不是虛擬的或抽象的(因此可以覆蓋)。

有關詳細信息,請參閱MSDN上的鏈接

試試這樣..

class Base 
{
 public virtual void Test() { ... }
}

class Subclass1 : Base 
{
 public sealed override void Test() { ... }
}

class Subclass2 : Subclass1 
{
 public override void Test() { ... } // FAILS!
// If `Subclass1.Test` was not sealed, it would've compiled correctly.
}

我正在重命名方法以便更好地理解。

public class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
    //MethodoBeInherited should be available
    //MethodNotToBeInherited should not be available
}

使用這種層次結構( 是一種關系 )是不可能的條件,因為DervicedClass是一個BaseClass。 因此,在繼承規則上,您必須能夠訪問所有BaseClass公共方法。

但是有一種替代方法可以解決這個問題 - 有一種關系 它不可能繼承並實現你想要的東西,因為你將破壞繼承規則。 因此,使派生類由基類組成,您將能夠實現它。

interface I
{
    void MethodToBeInherited(string input)
}

class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}

class DerivedClass : I
{
    public void MethodToBeInherited(string input)
    {
        b.MethodToBeInherited(input);
    }

    private BaseClass b;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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