我正在查看抽象类中的一些代码:
public virtual void CountX(){}
public virtual void DoCalculation() { ...code}
如果在派生类型中不必强制覆盖虚拟方法,为什么要在抽象类中声明一个空的虚方法呢?
答案 0 :(得分:43)
因为如果默认行为是什么都不做,但派生类可能想做某事。这是一个非常有效的结构。
它允许您的基本代码来调用它。当存在“BeforeXXX”和“AfterXXX”代码时,您往往会看到类似的设计,在基类中此代码为空,但该方法需要在那里进行编译。在派生类中,此代码是可选的,但需要虚拟化才能被覆盖。
它在抽象类中的事实不应该混淆它的行为。
一个例子:
abstract class Base
{
public void ProcessMessages(IMessage[] messages)
{
PreProcess(messages);
// Process.
PostProcess(messages);
}
public virtual void PreProcess(IMessage[] messages)
{
// Base class does nothing.
}
public virtual void PostProcess(IMessage[] messages)
{
// Base class does nothing.
}
}
class Derived : Base
{
public override void PostProcess(IMessage[] messages)
{
// Do something, log or whatever.
}
// Don't want to bother with pre-process.
}
如果这些方法(Pre,Post)是抽象的,那么所有派生类都需要来实现它们(可能是空方法) - 可以使用基础上的空虚方法删除的代码垃圾
答案 1 :(得分:8)
正如@Adam告诉你的那样,在很多情况下它是有道理的。当你创建一个抽象类时,这是因为你想为从那个派生的所有类创建一个公共接口;但是,在该继承级别,您将没有足够的信息来为该方法创建工作代码。
例如,如果使用 getArea()方法创建类图,则无法编写将正确计算的代码所有数字的区域。您必须等待编写矩形或圆(均来自图)的代码,以便能够编写为他们工作的代码。
答案 2 :(得分:5)
如果要覆盖MANDATORY并且不能在基类中写入默认逻辑,那么虚拟性是错误的,方法应该是抽象的。如果默认操作是什么都不做,而不是像Adam提到的那样,在基类中创建空虚拟方法是完全有效的结构
答案 3 :(得分:3)
当您将方法声明为抽象时,继承的类具有来覆盖该方法(提供实现)。这是强制性的。
当方法声明为虚拟时,继承者可以覆盖该方法并提供默认值以外的实现。
答案 4 :(得分:0)
从设计的角度来看,这闻起来很糟糕,并表明设计的实施处于不成熟的状态。如果派生特定基类的每个类都不需要某个方法,那么根据定义它不属于基类。您通常会发现此方法由基类的特定派生使用,并指示继承层次结构中的新接口或抽象层。