问题描述
我的目标是有一个抽象的Game
类,其构造函数接受一个GameEngine
,该类适用于派生的Game
类。这个抽象的Game
类将实现适用于所有Game
实现的通用方法。您可以将GameEngine
视为一种策略模式,Game
会将方法委托给该模式。
因此,在创建带有Game
的{{1}}时,我不在乎工厂返回的GameFactory
的什么实现。我只想确保通过适当的Game
实现构造Game
实现。但是,如果我只是从工厂返回原始类型GameEngine
,那么我当然会收到Game
警告。
此外,理想情况下,Raw use of parameterized class 'Game'
方法不必传递类型,而只是基于GameFactory.createGame(settings)
的某些属性来推断类型。
这是我所拥有代码的要旨:
settings
我是否滥用/误解了仿制药以实现我规定的目标?
仍然可以强制将适当的public abstract class GameEngine<T extends Game<T>> {
public void doSomethingallEnginesUnderstand(T game);
}
public class LocalGameEngine
extends GameEngine<LocalGame> {
}
public class RemoteGameEngine
extends GameEngine<RemoteGame> {
}
public abstract class Game<T extends Game<T>> {
private final GameEngine<T> gameEngine;
protected Game(GameEngine<T> gameEngine) {
this.gameEngine = gameEngine;
}
protected abstract T getSelf();
public final void doSomethingallEnginesUnderstand() {
gameEngine.doSomethingallEnginesUnderstand(getSelf());
}
}
public class LocalGame
extends Game<LocalGame> {
public LocalGame(LocalGameEngine gameEngine) {
super(gameEngine);
}
@Override
protected LocalGame getSelf() {
return this;
}
}
public class RemoteGame
extends Game<RemoteGame> {
public RemoteGame(RemoteGameEngine gameEngine) {
super(gameEngine);
}
@Override
protected RemoteGame getSelf() {
return this;
}
}
public class GameFactory {
// returns raw type Game
public Game createGame(GameSettings settings) {
if(settings.totalPlayers() > 1) {
return new RemoteGame(new RemoteGameEngine());
}
else {
return new LocalGame(new LocalGameEngine());
}
}
}
实现传递给构造函数,而不使Game
成为泛型类?
解决方法
我觉得您过度使用了泛型,而我发现Game<T extends Game<T>>
是一个过大的杀伤力。我将以这种方式设计它:
-
使
LocalGame
和RemoteGame
扩展Game
(无通用类型)。@Override
getSelf
方法时使用多态性:public class LocalGame extends Game { public LocalGame(LocalGameEngine gameEngine) { super(gameEngine); } @Override protected LocalGame getSelf() { return this; } }
public class RemoteGame extends Game { public RemoteGame(RemoteGameEngine gameEngine) { super(gameEngine); } @Override protected RemoteGame getSelf() { return this; } }
-
使
LocalGameEngine
和RemoteGameEngine
扩展GameEngine
(无通用类型)// actuyally,this abstract class can be an interface instead public abstract class GameEngine { public void doSomethingAllEnginesUnderstand(Game game) {} }
public class LocalGameEngine extends GameEngine { }
public class RemoteGameEngine extends GameEngine { }
-
使
Game
需要GameEngine
的任何子类,泛型部分只能在构造函数中使用,而无需使整个Game
泛型({ {1}}。Game<T>
-
整个
public abstract static class Game { private final GameEngine gameEngine; protected <T extends GameEngine> Game(T gameEngine) { this.gameEngine = gameEngine; } protected abstract Game getSelf(); public final void doSomethingAllEnginesUnderstand() { gameEngine.doSomethingAllEnginesUnderstand(getSelf()); } }
变得简单了:GameFactory