2010-03-18 107 views
5

我学习设计模式和代码示例我已经看到了约定​​,其中抽象类声明的方法,例如:抽象方法签名,继承和“做”的命名约定

public abstract class ServiceBase { 
... 

public virtual object GetSomething(); 

然后

protected abstract object DoGetSomething(); 

我的问题是,为什么存在这两种方法,因为他们似乎达到同样的目的。这是否使基类GetSomething()方法逻辑不能被继承类重写?但是再次,该方法被标记为虚拟的,因此无论如何它都可以被覆盖。这样在要求派生类实现者实现抽象方法的时候有什么用处呢?

+0

GetSomething应该是虚拟的吗? – JaredPar

+0

是的,它绝对是虚拟的。 –

回答

4

一个常见原因是围绕抽象方法进行标准处理。例如,也许抽象方法只能在某些情况下被调用 - 例如,样条线被网状化后。在这种情况下,在一个地方检查_areSplinesReticulated是有意义的 - 公共GetSomething方法 - 而不是要求抽象方法的每个实现都执行自己的检查。或者,也许GetSomething是90%的样板,但需要一些额外的逻辑或只有派生类可以提供的关键信息。

这是Template Method模式的一种形式。

非虚拟GetSomething意味着每个派生类都获得标准处理,并且只通过它们的自定义版本DoGetSomething进行参与。如果GetSomething是虚拟的,这意味着派生类可以绕过标准处理,如果他们想。这些都是一种可行的策略,具体取决于标准的GetSomething处理是否是类逻辑中不可或缺的一部分(例如不变量),还是基类想要给派生类赋予最大的灵活性。

0

我还没有看到你所描述的版本,其中“GetSomething()”是虚拟的,但我已经看到了(和书面)班这样的:

public abstract class Foo 
{ 
    protected abstract void DoBar(); 

    public void Bar() 
    { 
     // do stuff that has to happen regardless of how 
     // DoBar() has been implemented in the derived 
     // class 
     DoBar(); 
     // do other stuff 
    } 
} 

因为“酒吧”不是虚拟的(并且我想你也可以将其封闭以确保)在调用“DoBar”方法之前和之后,您有机会“注入”代码。这非常方便。