我正在尝试创建一个简单的国际象棋程序,我在实现典当促销时遇到了一个小问题。我有一个抽象类和6个类(King,Queen,Rook,Knight,Bishop和Pawn)扩展它。所以当一个棋子到达棋盘的另一端时,我希望他改变让我们说皇后。
最简单的方法是做这样的事情:
Public class Pawn extends Piece {
...
@Override
public void move(int toCol, int toRow) {
this.col = toCol; this.row = toRow;
if (toRow == endRow)
this = (Queen)this
}
}
这显然是不可能的,因为人们根本无法分配给这个。
所以我需要检测促销并从外部投射。但由于某些原因,我存储了两次配件。作为一个2D阵列的片断,但也作为每个玩家的2个片段列表。这意味着我需要在列表中找到pawn并将其删除,然后添加具有相同坐标的新女王,然后将她分配给棋盘[col] [row]。
我想知道是否有更好的方法来做到这一点。不知何故从“内部”改变对象的类。
答案 0 :(得分:5)
我不明白,你想要完成什么。如果您在物理棋牌游戏之后进行模型化,则您的棋子被丢弃,而是使用另一个棋子。所以pawn从你的游戏板中removed
,并且在原来的位置上有一个女王inserted
。
You can not simply change the class of an instance.
答案 1 :(得分:1)
首先,您可能不应该为不同的作品使用不同的课程。这似乎出现在每本面向对象的书中,并且真的没有意义。特别是因为您在外部告诉move
。
我只是把它写成一个带有枚举变量type
的类,然后从QUEEN
重新分配给PAWN
。
例如,这可能是它的样子。
public class Piece{
public static enum ChessType{PAWN, ROOK, BISHOP, KNIGHT, QUEEN, KING;}
private ChessType type;
...
public void move(int toCol, int toRow) {
switch(type){
case PAWN:
this.col = toCol; this.row = toRow;
if (toRow == endRow)
this = (Queen)this;
}
break;
... //Handle the rest
}
}
...
}
答案 2 :(得分:-1)
您可以让move
方法返回已移动的部分。像
@Override
public Piece move(int toCol, int toRow) {
if (toRow == endRow) {
return new Queen(toCol, toRow);
}
return new Pawn(toCol, toRow);
}
这样,您可以使Piece
对象不可变。