周期性的仿制药

时间:2012-02-23 22:55:46

标签: java

我正在努力做一些事情:

public interface Player<R>
{
    R takeTurn(Game game);
}

public interface Game
{
}

public class XPlayer
    implements Player<Interger>
{
    // XGame won't work because the interface takes Game
    public Integer takeTurn(final XGame game)
    {
        return (null);
    }
}

public class XGame
{
}

我所坚持的是我需要在游戏和播放器界面中进行哪些更改以使仿制药工作(我已经暂停了,而我脑子里还有一些头发:-)具体来说,我挂在哪里玩家需要知道游戏的类型,游戏需要知道玩家的类型。

3 个答案:

答案 0 :(得分:6)

这不是泛型问题(Game未输入)。

这是一个继承问题。试试这个:

public class XGame implements Game // added interface

答案 1 :(得分:1)

所以我们遇到的情况是我们有游戏和玩家,这些可能是子类。 TicTacToe GAME使用TicTacToe PLAYERS,反之亦然。

为此,请将所有类放在声明中。声明结果非常难看,但使用它的代码变得非常干净。

我喜欢在我正在使用的类系统中保持泛型类型列表的顺序相同。

abstract class Game<//
        G extends Game<G, P>, //
        P extends Player<G, P>> {
    P getCurrentPlayer() {return null;}
}

abstract class Player<//
        G extends Game<G, P>, //
        P extends Player<G, P>> {
    G getCurrentGame() {return null;
}

你使用那些抽象类:

class TTTGame extends Game<TTTGame, TTTPlayer> {}

class TTTPlayer extends Player<TTTGame, TTTPlayer> {}

class ChessGame extends Game<ChessGame, ChessPlayer> {}

class ChessPlayer extends Player<ChessGame, ChessPlayer> {}

等等。强大的打字意味着国际象棋棋手的游戏将成为国际象棋游戏,国际象棋游戏的玩家将成为国际象棋选手 - 在所有返回类型,参数和可见领域。

你甚至可以做一些技巧,比如以一种方式扩展继承层次结构而不是另一种方式。让我们说我们定义了一类游戏,玩家只有动作才能翻转硬币并报告头部或尾部。我们可以创建一个适用于任何coingame的硬币播放器,以及一种类型仍然是通用的,但它绑定P的硬币游戏。

class CoinGame<G extends CoinGame<G>> //
        extends Game<G, CoinPlayer<G>> {
}

class CoinPlayer<G extends CoinGame<G>> //
        extends Player<G, CoinPlayer<G>> {
    boolean flip() {
        return true;
    };
}

硬币游戏的子类只有一个类型参数,因为它们都是硬币玩家类型的玩家。大多数具体游戏都会将此参数绑定到自己:

class DontFlipHeads //
        extends CoinGame<DontFlipHeads> {
    class YouLose extends Exception {
    }

    void turn() throws YouLose {
        if (getCurrentPlayer().flip()) throw new YouLose();
    }
}

DontFlipHeads类知道它的播放器有一个翻转方法,因为它扩展了绑定了具有该方法的播放器类型的游戏,即使getCurrentPlayer()一般定义在继承层次结构的底部。

请注意,DontFlipHeads的播放器类需要有一个参数。因此:

…
DontFlipHeads game = new DontFlipHeads();
CoinPlayer<DontFlipHeads> player1 = new CoinPlayer<DontFlipHeads>();

game.addPlayer(player1, 1);

如果没有这种双向引用,则不需要这样做。但是因为引用,你可以

DontFlipHeads whatGame = player1.getGame();

没有任何演员。

答案 2 :(得分:0)

为什么不有这样的东西 -

    public Integer takeTurn(Game game)
      {
         XGame xGame = (XGame) game; // assuming XGame implements Game  
         return ...;
      }