2011-04-04 52 views
20

我是在抽象类中寻找一些代码:虚拟方法,而身体

public virtual void CountX(){} 

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

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

+0

virutal。是的:) – Heliac 2013-08-20 19:06:05

回答

6

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

例如,如果你创建类,与的getArea()方法,你将不能够编写是要正确计算该地区所有的数字代码。您必须等待编写代码矩形(均源自),以便能够为其编写工作代码。

+5

以下代码虽然在这种情况下,该方法应该是抽象的。由于您希望所有派生的形状计算其面积,因此不要将其视为“虚拟”。这种行为不应该是可选的并且被排除在外。 – gretro 2014-09-08 02:24:07

+4

好的。如果你有20辆来自基类车辆的车辆,其中10辆没有刹车装置,但是你需要brake()方法,将它定义为虚拟的(而不是抽象的) ,一个空的身体,而不是被迫覆盖它在所有这些类别中什么都不做。 – Baltasarq 2014-09-08 07:48:22

36

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

它允许您的基本代码来调用它。当有“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. 
    } 

如果这些方法(前,后)是抽象的,那么所有的派生类将需要实现它们(可能为空的方法) - 可使用移除代码垃圾在基地空的虚拟方法。

+0

+1 - 预处理和后处理是一个很好的例子。 – Town 2011-04-04 08:43:36

+0

+1:您将描述基本实现的位置作为_default_行为。这正是具有虚拟非抽象方法的目的。即使默认是“什么都不做”,那仍然是默认设置;) – 2011-04-05 13:03:10

+0

嗯,所以如果我有一个“什么都不做”的基本方法,*应该*我从这个调用base.DoNothingMethod(),DoNothingMethod,还是没关系省略那段代码? – Heliac 2013-08-20 19:17:54

3

当您将方法声明为抽象方法时,继承的类具有以覆盖该方法(提供实现)。这是强制性的。

当方法声明为虚拟时,继承者可以用覆盖该方法并提供一个不是默认的实现。

4

如果是强制重写并且没有默认逻辑可以写入基类,那么虚拟性是错误的,并且方法应该是抽象的。如果默认行动是什么都不做,就像亚当所说的那样,在基类中做空虚拟方法是完全有效的结构

0

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

+0

如果你打算投票。请至少提供一个理由。 – ComeIn 2014-10-27 03:09:06

+0

我同意Comeln。 DCastro的帖子在这里(http://stackoverflow.com/questions/22256157/empty-virtual-method-on-base-class-vs-abstract-methods)揭示了这一点。 – Kwex 2015-08-06 12:24:19