[英]Instantiating a child class that extends an abstract class, the abstract class having a parameter pointing to another different abstract class
我正在為我的 Object 面向 Java II 課程做一個項目,我在啟動它時遇到了麻煩,因為我似乎無法遵循我必須用自己的具體類覆蓋的抽象類是如何構建的邏輯(沒有遇到 StackOverflowError)。 我不允許在我的具體類中聲明任何新的 state 信息或修改給定的抽象類。
這是抽象“游戲”class 的代碼:
public abstract class Game
{
protected Board board; // the board for this game
protected Player p1; // the game's first player
protected Player p2; // the game's other player
protected Player winner; // the game's winner
protected int score1; // p1's score
protected int score2; // p2's score
protected Player currentPlayer; // the player whose turn it is to play
/**
* Constructor for objects of class Game
*
* @param board an empty, game-specific board to play the
* game on
*/
public Game(Board board)
{
this.board = board;
board.setGame( this );
score1 = score2 = 0;
}// constructor
/**
* Plays an entire game
*/
public void play()
{
setUp();
board.display();
while (! gameOver() )
{
p1.playAMove();
board.display();
if (gameOver())
break;
p2.playAMove();
board.display();
}// main game loop
wrapUp();
}// play method
/**
* Sets up the board in its initial configuration as well as
* the two players of this game
*/
public abstract void setUp();
/**
* Determines whether or not the game has ended
*/
public abstract boolean gameOver();
/**
* Finishes the game after a tie or a win
*/
public abstract void wrapUp();
}
這是抽象“板”class 的代碼:
public abstract class Board
{
protected Game game; // the game using this board
protected Piece[][] board; // the state of the board
protected int rows; // the vertical size of the board
protected int cols; // the horizontal size of the board
/**
* Constructor for objects of class Board
*
* @param game game the board is used for
* @param numRows number of rows of the board
* @param numColumns number of columns of the board
*/
public Board(Game game, int numRows, int numColumns)
{
this.game = game;
rows = numRows;
cols = numColumns;
board = new Piece[rows][cols];
}// constructor
/**
* Associates to this board the game that uses it
*
* @param game the game that uses this board
*/
public void setGame(Game game)
{
this.game = game;
}// setGame method
/**
* Returns the piece located at the given position or null
* if no piece is at that location; throws an exception if
* the location is off the board
*
* @param row the row index of the location
* @param column the column index of the location
* @return the piece at the given location or null
* if the location is empty
*/
protected Piece getPiece(int row, int column)
throws InvalidBoardPositionException
{
if (row < 0 || row >= rows || column < 0 || column >= cols)
throw new InvalidBoardPositionException(row,column);
return board[row][column];
}// getPiece method
/**
* Puts down the given piece at the given location; throws an
* exception if the location is off the board or already
* occupied
*
* @param piece the piece to place on the board
* @param row the row index of the target location
* @param column the column index of the target location
*/
protected void putPiece(Piece piece, int row, int column)
throws InvalidBoardPositionException
{
if ( row < 0 || row >= rows ||
column < 0 || column >= cols ||
! isEmpty(row,column) )
throw new InvalidBoardPositionException(row,column);
board[row][column] = piece;
}// putPiece method
/**
* Removes from the board the piece at the given location;
* throws an exception if the location is off the board or empty
*
* @param row the row index of the target location
* @param column the column index of the target location
*/
protected void removePiece(int row, int column)
throws InvalidBoardPositionException
{
if ( row < 0 || row >= rows ||
column < 0 || column >= cols ||
isEmpty(row,column) )
throw new InvalidBoardPositionException(row,column);
board[row][column] = null;
}// removePiece method
/**
* Returns true if and only if the specified location is
* empty
*
* @param row row index of the location being checked
* @param col column index of the location being checked
* @return true if and only if there is no piece at
* the location being checked
*/
protected boolean isEmpty(int row, int col)
{
return board[row][col] == null;
}// isEmpty method
/**
* Displays the board on the terminal window
*/
protected abstract void display();
}
我必須擴展這兩個類(GGame 擴展 Game,GBoard 擴展 Board),並在 GGame 中使用此代碼來啟動程序:
public static void newGame()
{
new GGame().play();
}
還有其他類,但我現在關心的實際上是讓程序創建一個“GGame”實例,這樣我就可以繼續前進了。 我試過這樣做:
/**
* Constructor
*/
public GGame() //needs to have no parameters
{
super(new GBoard());
}
但是,抽象“Board”class(“GBoard”必須擴展)的構造函數需要將“Game”實例傳遞給它。 但是如果我將“GGame”的一個實例傳遞給“GBoard”構造函數,它會無限循環,因為new GGame()
和new GBoard()
相互調用。
我會接受任何關於我能做什么的想法,並在必要時提供更多信息。 我不希望有人為我做這個項目,我只是被合法地卡住了,不知道如何進行。 我確定我錯過了一些東西。
如果不想修改抽象類的實現,則必須將null
傳遞給超類的構造函數,如下所示:
class BoardImpl extends Board {
BoardImpl() {
super(null, a, b);
}
}
class GameImpl extends Game {
GameImpl(Board board) {
super(board);
}
}
然后將 Board 實例傳遞給 Game 構造函數:
Board board = new BoardImpl();
Game game = new GameImpl(board);
另請注意,在 class 構造函數中傳遞this
,如下所示:
public Game(Board board)
{
this.board = board;
board.setGame( this );
score1 = score2 = 0;
}
是一個非常糟糕的做法,因為在傳遞this
實例時尚未完全構建。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.