试图在Java中访问子类变量

时间:2017-09-15 09:01:51

标签: 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;
            }

此代码段控制棋子的移动。在底部3行,它试图将Pawn类的isFirstMove变量更改为false,因为它不是Pawn的第一次移动。但我很难改变变量,因为pieceToMove对象基本上是Piece类(Pawn的超类),而不是Pawn类。我怎样才能顺利地做到这一点?

4 个答案:

答案 0 :(得分:4)

您将pieceToMove投射到Pawn,但变量的类型仍为Piece

试试这个:

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

答案 1 :(得分:2)

您可以修复演员表,但是您应该完全删除代码,因为它遵循非常危险的模式。当你这样做时

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

您正在设置代码,以便在添加新类型和对SomeType的更改时中断。这是一个非常糟糕的主意。

更好的方法是添加一个方法,通知任何一件它不再是第一步,并且无论它是否是Pawn都可以调用它:

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

答案 2 :(得分:1)

您应该将实例强制转换为Pawn

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

答案 3 :(得分:0)

首先看一下this,清楚地了解你在Java中投射的内容。

你会明白,如果你想访问变量,你将不得不创建一个新的对象实例

Pawn pawnToMove = (Pawn) pieceToMove;

然后你可以通过这样做来访问变量

pawnToMove .isFirstMove = false;

现在进一步深入,我认为你必须为你的对象创建一个setter,不要直接访问变量

pawnToMove.setFirstMove(false);

请注意,您可以在一个九中完成,而无需创建Pawn的新实例

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