没有身体的虚拟方法

Jef*_*yZ. 24 c# virtual inheritance

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

public virtual void CountX(){}

public virtual void DoCalculation() { ...code}
Run Code Online (Sandbox Code Playgroud)

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

Ada*_*rth 45

因为如果默认行为是什么都不做,但派生类可能想要做某事.这是一个完全有效的结构.

它允许您的基本代码调用它.当存在"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.
    }
Run Code Online (Sandbox Code Playgroud)

如果这些方法(Pre,Post)是抽象的,那么所有派生类都需要实现它们(可能是空方法) - 可以使用基础上的空虚方法删除的代码垃圾.

  • 这应该是答案 (3认同)

Bal*_*arq 10

正如@Adam告诉你的那样,在很多情况下它是有道理的.当你创建一个抽象类时,这是因为你想为从那个派生的所有类创建一个公共接口; 但是,在该继承级别,您将没有足够的信息来为该方法创建工作代码.

例如,如果使用getArea()方法创建类Figure,则无法编写能够正确计算所有数字区域的代码.你必须等待编写RectangleCircle(都来自)的代码,以便能够为它们编写工作代码.

  • 虽然在这种情况下,该方法应该是抽象的.将它保留为"虚拟"是没有意义的,因为您希望所有派生的形状计算它们的面积.此行为不应是可选的,并且不予理睬. (6认同)
  • 好的.例如,如果您有20辆来自基类车辆的车辆,其中10辆没有制动器,但是您需要使用brake()方法,将其定义为虚拟(非抽象)更为舒适,有一个空的身体,而不是被迫覆盖它在所有这些类中什么都不做. (4认同)

arc*_*hil 5

如果要覆盖MANDATORY并且不能在基类中写入默认逻辑,那么虚拟是错误的,方法应该是抽象的.如果默认操作是什么都不做,而不是像Adam提到的那样,在基类中创建空虚拟方法是完全有效的结构