我遇到了一个帖子,据说如果我们让Abstract类以这种方式进行调用,就会调用MustBeCalled()方法。
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
//could also be public if desired
protected abstract void AbstractMethod();
}
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
但是如何调用MustBeCalled()方法? 这里叫什么顺序?
答案 0 :(得分:3)
如果您先调用PerformFunction()
,那么所有内容都将按照预期的顺序执行,其中该顺序是按PerformFunction()
中的代码行顺序指定的。如果您直接致电AbstractMethod()
,则无法保证MustBeCalled()
将被调用。但是,我注意到您AbstractMethod()
标记为protected
,这意味着您班级的外部消费者将无法直接调用它。他们必须使用PerformFunction()
- 这很好,因为现在只有一种公共方式来调用你的内部方法,这样就可以保证你需要的顺序。
事实上,只有通过选择编写代码才能确保事情发生,才能保证事情的发生。例如,你不能保证代码将实现俄罗斯方块游戏,除非实际编写代码并选择以产生俄罗斯方块行为的方式实现它。类型系统和public / protected / private修饰符可以通过防止一些滥用来帮助一些(因为你的内部不可访问,因此你的模块的消费者不能调用它),但它们只能到目前为止。就是这种情况。
答案 1 :(得分:0)
您无法强制实现在调用时调用方法的方式。实现可以完全自己做,也可以什么也不做。
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
// this is a perfectly valid implementation
}
}
更好的实施可能是。
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
private void MustBeCalled()
{
}
protected virtual void AbstractMethod()
{
MustBeCalled();
}
}
这种重构工具至少会创建所需的样板代码:
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
base.AbstractMethod();
}
}
但是,覆盖AbstractMethod
的人仍然需要调用base.AbstractMethod
,编译器根本不会执行此操作。