C# 无实体的虚拟方法

C# 无实体的虚拟方法,c#,inheritance,virtual,C#,Inheritance,Virtual,我在看抽象类中的一些代码: public virtual void CountX(){} public virtual void DoCalculation() { ...code} 如果在派生类型中不强制重写抽象类中的空虚拟方法,为什么要在抽象类中声明该方法?因为如果默认行为是什么都不做,但派生类可能想做些什么。这是一个非常有效的结构 它允许您的基本代码调用它。当有“BeforeXXX”和“AfterXXX”代码时,您往往会看到类似的设计,在基类中,此代码为空,但方法需要在那里编译。在派生

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

public virtual void CountX(){}

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

如果在派生类型中不强制重写抽象类中的空虚拟方法,为什么要在抽象类中声明该方法?

因为如果默认行为是什么都不做,但派生类可能想做些什么。这是一个非常有效的结构

它允许您的基本代码调用它。当有“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)是抽象的,那么所有派生类都需要实现它们(很可能是空方法)——可以在基部使用空虚拟方法删除的代码垃圾。

当您将方法声明为抽象时,继承的类必须重写该方法(提供实现)。这是强制性的


当方法声明为虚拟时,继承者可以重写该方法并提供除默认值以外的实现。

如果必须重写,并且不能在基类中编写默认逻辑,则虚拟性是错误的,方法应该是抽象的。如果默认操作是什么也不做,就像Adam提到的那样,在基类中生成空的虚方法是完全有效的结构

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


例如,如果使用getArea()方法创建类Figure,则无法编写正确计算所有地物面积的代码。您必须等待为矩形圆形(两者均源自)编写代码,以便能够为它们编写工作代码。

从设计角度看,这很难闻,表明设计的实现处于不成熟状态。如果派生特定基类的每个类都不需要某个方法,则根据定义,该方法不属于基类。您通常会发现,基类的特定派生使用此方法,这表明继承层次结构中有一个新的接口或抽象层。

+1:您将基类实现描述为默认行为。这正是拥有虚拟非抽象方法的目的。即使默认值为“不做任何事”,这仍然是默认值;)嗯,如果我有一个“不做任何事情”的基方法,我应该从这个.DoNothingMethod调用base.DoNothingMethod(),还是可以省略那段代码?@Heliac-我有同样的问题,决定省略下面的代码,尽管在这种情况下,该方法应该是抽象的。将其保留为
virtual
是没有意义的,因为您希望所有衍生形状都计算其面积。这个行为不应该是可选的,应该被忽略。好的。比如说,如果您有二十辆从基类Vehicle派生的车辆,其中有十辆没有刹车的方法,但您需要brake()方法,那么将其定义为虚拟(而不是抽象)的空体会更舒服,我不会被强迫在所有这些级别上都不做任何事情,而是在
刹车
是可选责任的车辆上驾驶,如果你要投反对票的话。请至少提供一个理由,我同意Comeln的观点。DCastro在这里的帖子()更清楚地说明了这一点。