[英]cyclical generics
我正在嘗試采取以下措施:
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
{
}
我要堅持的是我需要在Game和Player界面中進行哪些更改才能使仿制葯正常工作(我停頓了一下,但我的頭上還有些毛毛:-)特別是我掛在Player需要處理的地方知道游戲的類型,並且游戲需要知道玩家的類型。
這不是一個泛型問題(未鍵入Game
)。
這是一個繼承問題。 嘗試這個:
public class XGame implements Game // added interface
因此,在這種情況下,我們會有游戲和玩家,而這些游戲和玩家可能會被細分。 TicTacToe游戲使用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> {}
等等。 強類型表示在所有返回類型,參數和可見字段中,國際象棋玩家的游戲將是國際象棋,而國際象棋游戲的玩家將是國際象棋。
您甚至可以做一些技巧,例如以一種方式擴展繼承層次結構,而不是另一種方式。 假設我們定義了一類游戲,其中玩家唯一的動作就是擲硬幣並報告正面或反面。 我們可以創建一個可用於任何投幣游戲的投幣游戲機,以及一個類型仍為通用但綁定了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類知道其播放器具有flip方法,因為即使在繼承層次結構的底部通常定義了getCurrentPlayer(),它也會擴展已綁定具有該方法的播放器類型的游戲。
請注意,DontFlipHeads的播放器類需要具有一個參數。 從而:
…
DontFlipHeads game = new DontFlipHeads();
CoinPlayer<DontFlipHeads> player1 = new CoinPlayer<DontFlipHeads>();
game.addPlayer(player1, 1);
如果沒有這種雙向引用,則沒有必要。 但由於引用是存在的 ,你可以
DontFlipHeads whatGame = player1.getGame();
沒有任何鑄造。
為什么沒有這樣的東西-
public Integer takeTurn(Game game)
{
XGame xGame = (XGame) game; // assuming XGame implements Game
return ...;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.