我有一个抽象类CreatureBehaviour
,它提供了TakeTurn
方法。这样做的目标是决定生物应该做什么,并且它应该通过回调提供响应。这是因为响应可能需要玩家输入,因此它不应该阻止其他进程。
public abstract class CreatureBehaviour {
public abstract void TakeTurn (Action<TurnAction> response);
}
继承自此,PlayerControl
类存储 response
回调以供以后决策。它的大部分内容都是不相关的,但最终它必须在玩家执行某些操作时调用响应
。
public class PlayerControl : CreatureBehaviour {
Action<TurnAction> responseCallback;
public override void TakeTurn(Action<TurnAction> response) {
responseCallback = response;
}
// Various UI callbacks that can send something to "responseCallback" when appropriate.
}
所有非玩家生物也需要能够发送回调。为了安全起见,我想确保回调始终被命中,因此我创建了一个抽象 NonPlayerControl
类来确保响应:
public abstract class NonPlayerControl : CreatureBehaviour {
protected abstract TurnAction TurnResponse ();
public override void TakeTurn (Action<TurnAction> response) {
response (TurnResponse ());
}
}
有了这个,我所有的非玩家生物行为都可以从 NonPlayerControl
派生,并简单地实现 TurnReponse()
。编译器保证所有脚本都会返回响应,而不是让回调挂起。请注意,PlayerControl
无法实现 TurnResponse()
,因为它需要保证立即返回,而这会阻塞其他进程。
所以我想从 NonPlayerControl
甚至可能从 PlayerControl
派生其他类,但我不想意外地从 CreatureBehaviour
派生另一个类> 并有错过回调的风险。
有什么方法可以“某种程度地密封”CreatureBehaviour
,以便它只能拥有这两个直接子级并阻止任何其他子级?如果没有,我可以在这里使用更好的模式吗?
最佳答案
您无法以“正常”方式为此做任何事情,但您可以考虑一个选择...
如果您只为 CreatureBehavior
类提供一个私有(private)构造函数,则将 PlayerBehavior
和 NonPlayerBehavior
嵌套在该类中,它们将有权访问私有(private)构造函数,但其他类不能...因此没有其他类可以从 CreatureBehavior
派生。
更简单的解决方案是:
CreatureBehavior
中的文档表明不应直接对其进行子类化- 编写单元测试来验证是否存在任何其他子类
当然,这只能测试您的代码,而不能测试其他程序集中的代码。如果您不需要其他程序集中的这些类,请将这些类设置为内部类而不是公共(public)类。即使您需要所有类都是公共(public)的,您也可以包含在 PlayerBehavior 和 NonPlayerBehavior 中实现的无操作抽象内部方法 - 这将阻止程序集外部的类派生自 CreatureBehavior
,因为它们无法实现内部抽象方法。
关于c# - 限制中间抽象类的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45132001/