[英]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.