C #Searled防止派生方法

时间:2015-03-23 11:01:46

标签: c# inheritance sealed

我试图阻止我的Base类派生它的一个方法,但似乎不可能按照我喜欢的方式去做,我认为我做错了。

你可以帮忙吗? :) 我真的想成功使用密封关键字!

以下是一些代码:

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#代码中听起来像什么?

6 个答案:

答案 0 :(得分:4)

如果这是第一个级别,除非标记为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
    }
}

答案 1 :(得分:4)

您只能密封覆盖基类中的虚方法的方法/属性。您的MyMethod2不是虚拟的,因此无法密封。事实上,它并不是因为它不是虚拟的,所以它是隐含的!

答案 2 :(得分:1)

您需要其他级别的继承才能使用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 says一样,默认情况下C#中的方法是密封的。

相反,为了能够覆盖方法,无论如何都必须将其标记为virtual,因此您的问题似乎根本不是问题。只需将MyMethod1标记为virtual,以便可以覆盖它,MyMethod2将保持非虚拟状态,因此根本不可覆盖。

答案 3 :(得分:0)

sealed关键字隐含在基类中的任何方法中,该方法不是虚拟的或抽象的(因此可以覆盖)。

有关详细信息,请参阅此link on MSDN

答案 4 :(得分:0)

试试这个..

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.
}

答案 5 :(得分:0)

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

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;
}