为什么抽象类应该实现抽象基类的抽象方法?

时间:2010-07-17 13:37:29

标签: c# .net design-patterns abstract-class

在以下示例中,类Derived实现了类method中的抽象方法Main。但我想不出在抽象Derived类'实现中填写方法体的原因。当然,我应该只在实际类中实现抽象方法。

那我怎么能避免这样做呢?我还可以做些什么?

abstract class Main
{
    public abstract void method();
}
abstract class Derived : Main
{
    public override void method()
    { 
    }
}

class RealClass : Derived
{

}

3 个答案:

答案 0 :(得分:9)

通常,如果有人指定抽象类具有抽象方法,那么要么是因为该类依赖于该方法所做的某些操作,要么是因为它是预期API的一部分,它对于它没有意义此时要实现的父类。在任何一种情况下,一旦你进入类的非抽象实现,必须是一个实现。

另请注意,如果要实现接口,则需要说明该接口的实现方式,即使您只是调用成员abstract并将责任传递给子类

public interface IPet {string GetNoise(); int CountLegs(); void Walk();}
public abstract class Pet : IPet
{
    public string Name {get; set;}
    public abstract string GetNoise(); // These must be here
    public abstract int CountLegs();
    public abstract void Walk();
}

在实现子类时,您可以根据具体情况选择一些。如果您的实现本身是一个抽象类,则不需要实现抽象方法。

public abstract class Quadruped : Pet
{
    public override int CountLegs () { return 4; }
}

如果您的实现是非抽象的,但该方法的标准原因确实不适用于您的情况,您可以执行无操作方法(在void方法的情况下),或返回一些虚拟value,或者甚至抛出一个NotImplementedException来指示永远不应该首先调用该方法。

public class Fish : Pet
{
    public override string GetNoise() {return "";} // dummy value: fish don't make noise
    public override int CountLegs() {return 0;}
    public override void Walk() {} // No-op
    // public override void Walk() { throw new NotImplementedException("Fish can't walk"); }
}

这会回答你的问题吗?

答案 1 :(得分:4)

如果method中没有Derived的实现,那么您也可以将Derived抽象为:

abstract class Derived : Main
{
}

class RealClass : Derived
{
    public override void method() { ... }
}

编辑:澄清注释 - 如果子类中没有有意义的抽象方法实现,则不需要提供。然而,这将要求派生类本身是抽象的,并且必须在子类链的某处将某个实现提供给某个具体的子类。我并不是说你应该将method的实现留空,因为它在问题中,而是删除Derived中的覆盖并将类标记为抽象。这迫使RealClass提供一个实现(或者本身标记为抽象)。

答案 2 :(得分:0)

所有非抽象后代类必须提供抽象方法的具体实现。如果您不提供实现,则无法调用该方法。

如果某些具体类没有明显正确的抽象方法实现,那么您的对象设计是不正确的。也许你应该有一个带有一些抽象方法的抽象类(但不是全部)。那个班可以有一个抽象的后代和一些具体的后代。