我可以以某种方式强制派生类始终调用重写的方法基础吗?
public class BaseClass
{
public virtual void Update()
{
if(condition)
{
throw new Exception("..."); // Prevent derived method to be called
}
}
}
然后在派生类中:
public override void Update()
{
base.Update(); // Forced call
// Do any work
}
我搜索并发现了使用非虚拟Update()以及受保护的虚拟UpdateEx()的建议。它感觉不是很整洁,是不是有更好的方法?
我希望你能得到这个问题,我很抱歉任何不好的英语。
答案 0 :(得分:29)
使用template method pattern - 不要覆盖需要做一些工作的基本方法,覆盖一个特定的位,它可以是抽象的,也可以是基类中的无操作。 (关于是否使其成为无操作或抽象的决定通常是相当明显的 - 基类本身是否有意义,作为具体类?)
听起来这基本上是你用UpdateEx
找到的模式 - 虽然它通常是UpdateImpl
或类似的经验。在我看来,作为一个模式,这没有任何问题 - 它避免强迫所有派生类编写相同的代码来调用基本方法。
答案 1 :(得分:2)
我认为您发现的建议很好。
唯一不能避免从基类构造函数中的子类调用的基类方法。
答案 2 :(得分:2)
我认为拥有一个非虚拟基础成员可以调用可以扩展的虚拟“钩子”,这是解决此类问题的最常见方法。
根据您的使用情况,您可能希望使用event
,但实现事件的通常模式是使用虚拟OnEvent
方法,子类可以覆盖而不是添加事件处理程序,所以在你的例子中它归结为同样的事情。
答案 3 :(得分:2)
这让我有点了解Update和UpdateEx的样子。这是一个可能对其他人有帮助的代码示例。
public class BaseClass
{
// This is the Update that class instances will use, it's never overridden by a subclass
public void Update()
{
if(condition);
// etc... base class code that will always run
UpdateEx(); // ensure subclass Update() functionality is run
}
protected virtual void UpdateEx()
{
// does nothing unless sub-class overrides
}
}
子类永远不会有Update()的任何实现。它将使用UpdateEx()将实现添加到Update();
public class ConcreteClass : BaseClass
{
protected override void UpdateEx()
{
// implementation to be added to the BaseClass Update();
}
}
ConcreteClass的任何实例都将使用Update()的BaseClass实现,但ConcreteClass使用UpdateEx()扩展它。