重铸“这个”解决方法
Posted
技术标签:
【中文标题】重铸“这个”解决方法【英文标题】:Recasting of 'this' workaround 【发布时间】:2015-02-20 23:03:24 【问题描述】:我正在尝试创建一个简单的国际象棋程序,但在实施典当提升时遇到了一个小问题。我有一个抽象类 Piece 和 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
这显然是不可能的,因为不能简单地分配给 this。
所以我需要检测促销并从外部投放。但由于某些原因,我将片段配置存储了两次。作为一个 2D 棋子数组,也可以作为每个玩家的 2 个棋子列表。这意味着我需要在列表中找到 pawn 并将其删除,然后添加具有相同坐标的新皇后,然后将她分配给 board[col][row]。
我想知道是否有更好的方法来做到这一点。以某种方式从“内部”更改对象的类。
【问题讨论】:
为对象实例更改对象的类类型不是 Java 允许的。相反,您可能会考虑删除 pawn 实例并将其替换为新的 Queen 实例。或者......你可以有一个表示类型的枚举和一个成员变量来将它保存在你的 Piece 类中并以这种方式切换类型...... 你明白演员表的意思吗?转换对象引用不会以任何方式将对象从一种类型转换为另一种类型,因此您不能使用它将Pawn
对象转换为Queen
对象。强制转换所做的唯一事情就是告诉编译器您要暂时禁用类型检查。检查仍将在运行时完成,当检查失败时,您将收到 ClassCastException
。
基本上你的mini乘用车可以换成SUV,但是mini不能换成SUV。
【参考方案1】:
我不明白,你想要完成什么。如果您仿照物理国际象棋游戏,您的棋子将放下并使用另一个棋子代替。因此,棋盘上的棋子是removed
,而后棋子的前位置是inserted
。
You can not simply change the class of an instance.
【讨论】:
【参考方案2】:首先,您可能不应该为您的不同部分使用不同的类。这似乎出现在每本面向对象的书籍中,但实际上没有任何意义。尤其是因为你在外部告诉move
。
我只是把它写成一个带有枚举变量type
的类,然后将它从PAWN
重新分配给QUEEN
。
例如,它可能是这样的。
public class Piece
public static enum ChessTypePAWN, 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
...
【讨论】:
【参考方案3】:你可以让你的move
方法返回移动的部分。类似的东西
@Override
public Piece move(int toCol, int toRow)
if (toRow == endRow)
return new Queen(toCol, toRow);
return new Pawn(toCol, toRow);
这样,您可以使您的 Piece
对象不可变。
【讨论】:
以上是关于重铸“这个”解决方法的主要内容,如果未能解决你的问题,请参考以下文章