限制子类继承某些基类方法

时间:2012-01-20 11:01:19

标签: c# override class-design

using System;

public class Base
{
    public Base()
    {
    }

    public void M1()
    {
    }

    public void M2()
    {
    }

    public void M3()
    {
    }
}

public class Derived : Base
{
    //this class should get only method 1
}

public class SecondDerived : Base
{
    //this class should get only method 2 and method3
}

要求是:基类包含3种方法M1M2M3
派生类应仅继承M1,而SecondDerived应仅继承M2M3

如何做到这一点?

4 个答案:

答案 0 :(得分:3)

您不能有选择地继承这样的方法。派生类自动继承基类的所有公共方法。我建议你将Base类拆分为两个类:

public class Base1
{
    public Base1()
    {
    }

    public void M1()
    {
    }
}

public class Base2
{
    public void M2()
    {        
    }

    public void M3()
    {       
    }
}

public class First : Base1

public class Second : Base2

答案 1 :(得分:3)

你不能这样做。继承意味着“IS A”关系。

如果SecondDerived没有M1(),则它与class Base的引用不兼容。

所以也许你不应该使用继承来解决你正在解决的任何问题。

答案 2 :(得分:0)

无法通过继承做你想做的事。

似乎你无意覆盖,你只想有选择地从基类“继承”行为。你可以使用“有一个”关系来做到这一点:

public class Base
{
     internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary

     public Foo Mehtod1() {...}
     public Foo Mehtod2() {...}
     public Foo Mehtod3() {...}
}

然后只需执行以下操作:

class A
{
     private Base internalBase;

     public A() { this.internalBase = new Base(); }

     public Foo Method1() { return this.internalBase.Method1(); }
}

class B
{
     private Base internalBase;

     public A() { this.internalBase = new Base(); }

     public Foo Method2() { return this.internalBase.Method2(); }
     public Foo Method3() { return this.internalBase.Method3(); }
}

更新:可能的替代解决方案是制作Base类方法virtual并在派生类中覆盖它们,将NotSupportedException投入其中您不希望该类可用的方法。我真的不喜欢这个解决方案,但它的优点是不会失去多变量继承,如果你有一些所有派生类将共享的核心基本功能,那么这可能是有用的(在你的例子中,你似乎暗示它们不会)。

答案 3 :(得分:0)

可以通过添加Obsolete属性

来实现
public class A
{
    public virtual void M1() { }
    public void M2() { }
    public void M3() { }
}

public class B : A
{
    [Obsolete("You can not use this", true)]
    public sealed override void M1()
    {

    }
}

public class C : B
{
    public void Test()
    {
        // Will show error 
        base.M1();

    }
}