简体   繁体   English

实例化一个扩展抽象 class 的子 class,抽象 class 具有指向另一个不同抽象 ZA2F2ED4F8EBC2CBBDZC21A 的参数

[英]Instantiating a child class that extends an abstract class, the abstract class having a parameter pointing to another different abstract class

I am working on a project for my Object Orientated Java II course, and I am having trouble with starting it, as I can't seem to follow the logic of how the abstract classes I have to override with my own concrete classes are constructed (without running into a StackOverflowError).我正在为我的 Object 面向 Java II 课程做一个项目,我在启动它时遇到了麻烦,因为我似乎无法遵循我必须用自己的具体类覆盖的抽象类是如何构建的逻辑(没有遇到 StackOverflowError)。 I am not allowed to declare any new state information in my concrete classes or modify the given abstract classes.我不允许在我的具体类中声明任何新的 state 信息或修改给定的抽象类。

Here is the code for the abstract "Game" class:这是抽象“游戏”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();

}

Here is the code for the abstract "Board" class:这是抽象“板”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();

}

I have to extend both classes (GGame extends Game, GBoard extends Board), and use this code in GGame to start the program:我必须扩展这两个类(GGame 扩展 Game,GBoard 扩展 Board),并在 GGame 中使用此代码来启动程序:

public static void newGame()
{
    new GGame().play();
}

There are other classes, but all I care about for now is actually getting the program to create an instance of "GGame" so I can move forward.还有其他类,但我现在关心的实际上是让程序创建一个“GGame”实例,这样我就可以继续前进了。 I've tried doing this:我试过这样做:

/**
 * Constructor
 */
public GGame()   //needs to have no parameters
{
    super(new GBoard());
}

However, the constructor of the abstract "Board" class (which "GBoard" has to extend) requires an instance of "Game" to be passed to it.但是,抽象“Board”class(“GBoard”必须扩展)的构造函数需要将“Game”实例传递给它。 But if I pass an instance of "GGame" into the "GBoard" constructor it loops infinitely as new GGame() and new GBoard() call each other.但是如果我将“GGame”的一个实例传递给“GBoard”构造函数,它会无限循环,因为new GGame()new GBoard()相互调用。

I'll take any ideas about what I can do, and will provide more info if necessary.我会接受任何关于我能做什么的想法,并在必要时提供更多信息。 I don't want someone to do the project for me, I'm just legitimately stuck and don't know how to proceed.我不希望有人为我做这个项目,我只是被合法地卡住了,不知道如何进行。 I'm sure I'm missing something.我确定我错过了一些东西。

If you don't want to modify the implementation of abstract classes, you must pass null to the constructor of the superclass as follows:如果不想修改抽象类的实现,则必须将null传递给超类的构造函数,如下所示:

class BoardImpl extends Board {
    BoardImpl() {
        super(null, a, b);
    }
}

class GameImpl extends Game {
    GameImpl(Board board) {
        super(board);
    }
}

and then pass the Board instance to the Game constructor:然后将 Board 实例传递给 Game 构造函数:

Board board = new BoardImpl();
Game game = new GameImpl(board);

also note that passing this in the class constructor like this:另请注意,在 class 构造函数中传递this ,如下所示:

public Game(Board board)
{
    this.board = board;
    board.setGame( this );
    score1 = score2 = 0;
}

is a very bad practice because at the time of passing this instance is not yet fully constructed.是一个非常糟糕的做法,因为在传递this实例时尚未完全构建。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM