没有身体的虚拟方法

时间:2011-04-04 08:33:41

标签: c# inheritance virtual

我正在查看抽象类中的一些代码:

public virtual void CountX(){}

public virtual void DoCalculation() { ...code}

如果在派生类型中不必强制覆盖虚拟方法,为什么要在抽象类中声明一个空的虚方法呢?

5 个答案:

答案 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)

从设计的角度来看,这闻起来很糟糕,并表明设计的实施处于不成熟的状态。如果派生特定基类的每个类都不需要某个方法,那么根据定义它不属于基类。您通常会发现此方法由基类的特定派生使用,并指示继承层次结构中的新接口或抽象层。