我有一个简单游戏的代码,其中必须实现AgentInterface才能为游戏中的一个角色创建代理控制器.GameState是一个实现GameStateInterface的类,实现此接口的对象可以传递给代理,因此代理可以从游戏状态读取和分析数据,并且代理必须返回相应的操作(作为int返回)角色应该采取.
这是代理必须实现的AgentInterface:
public interface AgentInterface {
// the return value specifies the direction of the joystick
public int action(GameStateInterface gs);
}
Run Code Online (Sandbox Code Playgroud)
使用名为MyAgent的代理运行游戏:
GameState gs = new GameState();
AgentInterface agent = new MyAgent();
while (true) {
// more code here
int bestAction = agent.action(gs)
// more code here
}
Run Code Online (Sandbox Code Playgroud)
但是,GameState中存在一些代理无法访问的信息,因为这会欺骗控制器.但是,执行从GameStateInterface到GameState的转换转换将允许代理访问GameStateInterface中未定义的信息,如下所示:
public MyAgent implements AgentInterface {
public int action(GameStateInterface gs) {
int nLives = ((GameState) gs).nLivesRemaining; // IS IT POSSIBLE TO DENY/PREVENT THIS CAST??
// Do more stuff here
return BestAction;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否可以阻止转换?我知道多态性是Java和面向对象编程语言的主要特性之一,但在这种情况下我想避免转换.
我知道这可以通过许多其他方式解决,但我很想知道是否可以这样做.
提前致谢.
Sim*_*ann 12
据我所知,不可能拦截类型转换并拒绝它(例如,通过抛出ClassCastException).
但是,您可以简单地使用代理模式来控制对实际GameState对象的访问,而不是试图拒绝类型转换.只需实现一个代理类,它只实现GameStateInterface并让它将所有方法调用转发给GameState对象.现在,不是将实际的GameState对象引用传递给action方法,而是将它传递给代理类的实例.
通常,您不能阻止在Java中强制转换对象。收到对您的引用的代码GameState
将能够在该对象上调用任何非私有,不受保护的方法。即使可以防止投射,它仍然可以使用反射。
如果Agent
代码在您的控制之下,则只需保持简单即可,不要进行转换。如果其他人编写Agent
类,则可以创建一个代理类,该代理类接受GameState对象,并且仅实现GameStateInterface的方法。
class GameStateProxy implements GameStateInterface {
private GameStateInterface state;
public GameStateProxy(GameState state) {
this.state = state;
}
public int someMethodInGameStateInterface(int x) {
return state.someMethodInGameStateInterface(x);
}
// other methods ...
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建一个代理并像这样传递它:
GameStateInterface proxy = new GameStateProxy(gameState);
int bestAction = agent.action(proxy);
Run Code Online (Sandbox Code Playgroud)
接收a的代码GameStateProxy
只能访问中的方法GameStateInterface
。