简体   繁体   中英

Trying to access a subclass variable in Java

public void movePiceTo(int x, int y, Piece pieceToMove) {

    if(pieceToMove.canMove(board, pieceToMove.getX(), pieceToMove.getY(), x, y)){ //Check if the piece canMove to the location

        if(board[x][y] == null) { //Check if the location is empty

            removePiece(pieceToMove.getX(), pieceToMove.getY());
            board[x][y] = pieceToMove;

            if(pieceToMove instanceof Pawn) {
                pieceToMove = (Pawn)pieceToMove;
                pieceToMove.isFirstMove = false;
            }

This code snippet controls the move of a chess Piece. At the bottom 3 lines, it tries to change the isFirstMove variable of a Pawn class to false since it is not Pawn's first move any more. But I am having hard time changing the variable because the pieceToMove object is basically a Piece class (superclass of Pawn), not a Pawn class. How can I do this smoothly?

You cast pieceToMove to Pawn , but the type of the variable is still a Piece .

Try this:

if(pieceToMove instanceof Pawn) {
    Pawn pawnToMove = (Pawn) pieceToMove;
    pawnToMove .isFirstMove = false;
}

You can fix the cast, but you should eliminate the code altogether, because it follows a very dangerous pattern. When you do this

if(item instanceof SomeType) {
    SomeType castItem = (SomeType)item;
    castItem.doSomethingSpecial();
}

you are setting your code up to break on adding new types and on changes to SomeType . This is a very bad idea.

A better approach is to add a method that informs any piece that it is no longer the first move, and call it regardless of whether it is a Pawn or not:

class Piece {
    public void setMoved() {
        // do nothing
    }
    ...
}
class Pawn extends Piece {
    private boolean isFirstMove = true;
    public void setMoved() {
        isFirstMove = false;
    }
    ...
}
...

removePiece(pieceToMove.getX(), pieceToMove.getY());
board[x][y] = pieceToMove;
pieceToMove.setMoved(); // <<== The instanceof check is gone

You should cast the instance to Pawn class for that

Pawn pawn = (Pawn)pieceToMove;
pawn.isFirstMove = false;

First of all take a look at this to clearly understand what you is casting in Java.

Thent you will understant that if you want to acces the variable you will have to create a new instance of the object

Pawn pawnToMove = (Pawn) pieceToMove;

Then you can acces the variable by doing this

pawnToMove .isFirstMove = false;

Now to go deeper, i think you must create a setter for your object to don't acces the varaible directly

pawnToMove.setFirstMove(false);

Notice that you can do it in a in one nine without having to create a new instance of Pawn

((Pawn) pieceToMove).setFirstMove(false);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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