如何限制层次结构中的覆盖?

fle*_*her 7 .net c# inheritance overriding

这是一个例子,我只是想知道它将如何实现.

我想只启用子类Animal来设置它们拥有的腿数,但我仍然希望它们能够设置自己的颜色.因此,我想在层次结构中进一步限制类,然后再更改此Legs属性.

public abstract class Animal
{
    public string Colour { get; protected set; }
    public int Legs { get; protected set; }

    public abstract string Speak();
}

public class Dog : Animal
{
    public Dog()
    {
        Legs = 4;
    }

    public override string Speak()
    {
        return "Woof";
    }
}

public sealed class Springer : Dog
{
    public Springer()
    {
        Colour = "Liver and White";
    }
}

public sealed class Chihuahua : Dog
{
    public Chihuahua()
    {
        Colour = "White";
    }

    public override string Speak()
    {
        return "*annoying* YAP!";
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,我想消除这种子类:

public sealed class Dalmatian : Dog
{
    public Dalmatian()
    {
        Legs = 20;
        Colour = "Black and White";
    }
}
Run Code Online (Sandbox Code Playgroud)

这将如何实现?

我知道我可以通过在父类中密封函数的实现来停止覆盖子类.我尝试了这个Legs属性,但我无法让它工作.

谢谢

mdm*_*dma 11

在某种程度上,这违背了OO原则.您的超类Animal提供了一个合同,其中包括Legs的set/get.然后,您希望子类能够限制该接口禁止设置Legs.由于子类化提供了"is-a"关系,因此限制接口与此相反,这意味着子类不是真正的子类型,因为不存在set Legs方法.

我会从Animal中删除Legs属性的setter,因为这是一个实现细节.相反,只需要一个抽象的吸气剂.然后,子类可以通过返回硬编码值或使用字段来存储值来决定如何最好地实现它.


Mar*_*k H 10

不要让Legs成为抽象类的字段,而应该只将它设为属性(删除setter),并使其成为抽象的.

在动物

public abstract int Legs { get; }
Run Code Online (Sandbox Code Playgroud)

在狗

public override sealed int Legs { get { return 4; } }
Run Code Online (Sandbox Code Playgroud)


Dea*_*n J 5

在Java中,您将使getter和setter成为最终方法,因此无法覆盖它们.在C#中,我相信你想要的关键词是"密封的"; 你要密封方法,但不是整个子类.

您将变量本身设为私有,因此子类必须使用getter/setter来访问变量.

  • +1只是尝试了密封方法和属性而这个工作,派生类不能覆盖密封成员.每天学些新东西 :-) (2认同)