我正在学习设计模式,在代码示例中,我看到了抽象类声明方法的约定,例如:
public abstract class ServiceBase {
...
public virtual object GetSomething();
然后
protected abstract object DoGetSomething();
我的问题是为什么存在这两种方法,因为它们似乎有相同的用途。这是为了让继承的类不能覆盖基类GetSomething()方法逻辑吗?但话说再次,该方法被标记为虚拟,所以无论如何它都可以被覆盖。在无论如何都可以调用虚方法时,要求派生类实现者实现抽象方法有什么用呢?
答案 0 :(得分:4)
一个常见的原因是围绕抽象方法进行标准处理。例如,也许抽象方法只能在某些情况下调用 - 比如,在样条线被网格化之后。在这种情况下,在一个地方检查_areSplinesReticulated是有意义的 - 公共GetSomething方法 - 而不是要求抽象方法的每个实现都执行自己的检查。或者GetSomething可能是90%的样板,但需要一些额外的逻辑或只有派生类可以提供的关键信息。
这是Template Method模式的一种形式。
非虚拟GetSomething意味着每个派生类都获得标准处理,并且只能通过其自定义版本的DoGetSomething参与。如果GetSomething是虚拟的,那意味着派生类可以在需要时绕过标准处理。这些都是可行的策略,取决于标准GetSomething处理是否是类逻辑(例如不变量)的组成部分,或者基类是否希望为派生类赋予最大的灵活性。
答案 1 :(得分: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
}
}
因为“Bar”不是虚拟的(我想你也可以密封它以确保)你有机会在调用“DoBar”方法之前和之后“注入”代码。它非常方便。