Java中泛型类的泛型类

时间:2010-02-19 19:18:21

标签: java generics

我有一个类层次结构设置如下:

public abstract class GameController
public abstract class Game

我想使用通用的GameController类,因此它需要特定的Game子类,所以我将其更改为:

public abstract class GameController<GameType extends Game>
public abstract class Game

但是我还希望有一个通用游戏来获取特定的玩家子类,所以我把它改为:

public abstract class GameController<GameType extends Game<PlayerType>, PlayerType extends Player>
public abstract class Game<PlayerType extends Player>

有没有更好的方法来解决这个问题,所以我不必两次声明PlayerType(在GameController子类和Game子类中)?

修改

GameController是一个网络类,它接收post和get请求,并将它们转换为更接近游戏需求的东西,然后是一个子类,比如MyGameController,进一步转换发布到方法调用中的byte []特定的游戏类,MyGame说。代码示例:

GameController:

public abstract class GameController<GameType extends Game<PlayerType>, PlayerType extends Player> {
    private Hashtable<String, GameType> games;
    public MultiplayerMain() {
        super();
        games = new Hashtable<String, GameType>();
    }
    protected abstract GameType createGame(InputStream in, String gameId);
    protected abstract PlayerType createPlayer(InputStream in, GameType game, String playerId);
    protected abstract byte[] gameAction(InputStream in, GameType game, PlayerType player);

    //Other stuff that calls createGame, createPlayer, and gameAction
}

游戏:

public abstract class Game<PlayerType extends Player> {
    private Hashtable <String, PlayerType> players = new Hashtable<String, PlayerType>();
    public final String gameId;
    public Game (String id) {
        gameId = id;
    }
    public abstract byte[] getGameState();
    public abstract byte[] getGameState(PlayerType player);
    final PlayerType getPlayer(String userId) {
        return players.get(userId);
    }
    final void addPlayer(PlayerType player) {
        players.put(player.userId,player);
        playerAdded(player);
    }
    final void removePlayer(PlayerType player) {
        players.remove(player);
        playerRemoved(player);
    }
    protected void playerAdded(PlayerType player) {}
    protected void playerRemoved(PlayerType player) {}
}

MyGameController:

public class MyGameController extends GameController<MyGame,MyPlaer> {
    protected MyGame createGame(InputStream in, String gameId) {
        byte[] data = getInitializationData(in);
        return new MyGame(gameId,data);
    }

    protected byte[] gameAction(InputStream in, MyGame game, Player player) {
        byte[] data = getData(in);
        MyGame.methodSpecificToMyGameClassBasedOnInputStream(data);
        return game.getGameState(player);
    }

    protected Player createPlayer(InputStream in, MyGame game, String playerId) {
        byte[] otherData = getOtherData(in,game)
        return new MyPlayer(playerId,otherData);
    }
}

MyGame:

public class MyGame extends Game<MyPlayer> {

    public MyGame(String id) {
        //...
    }

    public byte[] getGameState() {
        //...
    }

    public byte[] getGameState(Player user) {
        //...
    }

    public void methodSpecificToMyGameClassBasedOnInputStream(byte[] data) {
        //...
    }
}

3 个答案:

答案 0 :(得分:3)

你需要仿制药吗?相反,您可以将Player注入GameGame注入GameController吗?

public class Game {
    private final PlayerType playerType;

    public Game(PlayerType playerType) {...}

}

public class GameController {
    private final Game game;

    public GameController(Game game) {...}
}

答案 1 :(得分:0)

我不确定您是否需要在游戏控制器中定义PlayerType。您可以执行以下操作:

public abstract class GameController<GameType extends Game<?>>
public abstract class Game<PlayerType extends Player>

gameController.getPlayer()只能返回一个Player,但你仍然可以使用gameController.getGame()。getPlayer()返回一个PlayerType。

编辑:基于您提供的方法签名,不,我没有看到声明泛型类型而不声明两次PlayerType的方法。

我同意其他人说你的模型太耦合了。感觉gameAction不应该关心它需要什么类型的游戏或玩家。

答案 2 :(得分:0)

看起来你真的把GameController的定义与Game和GameType的继承层次紧密联系起来;类似于Game to Player和PlayerType。我鼓励你把这种关系更加宽松地结合起来;正如其他海报所暗示的那样,组合几乎肯定是正确的方式,因为你描述的是“有一种”关系。