我是Java的新手,正在尝试构建运行国际象棋游戏的逻辑。我有一个名为"Piece"的超类和国王、骑士、王后等的子类。我正在尝试实现一个移动方法,其中我动态确定棋子的类型,然后调用该棋子的相应移动方法。例如:
int typeOfPiece = _board[startX][startY]._theKind;
Piece myPiece;
switch(typeOfPiece)
{
case 1:
myPiece = new Pawn(startX, startY, team);
case 2:
myPiece = new Rook(startX, startY, team);
case 3:
myPiece = new Knight(startX, startY, team);
}
boolean myPiece.canMove(endX, endY);
有没有办法确保 canMove 方法将在此示例中由正确类型的片段调用?
谢谢
如果您的板子可以容纳Piece
对象而不是int
值,那么您可以执行以下操作:
Piece piece = _board[x][y];
piece.canMove(...);
Piece
类将定义一个canMove
方法,其所有子类将使用自己的策略实现。
覆盖所有子类中的canMove
,并在父类Piece
中使其抽象。
如果你的子类覆盖了超类'Piece'上的canMove方法,myPiece.canMove(endX, endY)就足够了。根据 myPiece 引用指向的对象类型,在运行时 jvm 将决定它应该调用哪个方法。这称为动态方法调度
我要做的是创建一个抽象类或接口来表示Piece
对象的行为和属性。
然后,我将有实现/扩展 piece 类的类,每个类都用 canMove
方法表示自己的行为。
实例化你的对象,然后在你的代码中,你只需获取驻留在位置 (x, y) 的Piece
对象并调用 canMove
。这会将行为委托给适当的子类,使您的代码更简洁、更易于维护和灵活。
拥有抽象类或接口,而不是为Piece
对象提供具体类,(在我看来)是优势,因为它迫使每个部分实现这种行为,而不是简单地继承它。
我建议你使用Enum来实现一个抽象类Piece而不是int的2d数组来表示板,例如,你可以通过这样做来避免幻数。
你在问题中所做的并不是真正利用多态性,因为你是通过程序代码决定作品的类型。
我建议你稍微改变一下你的Desing:不要在每次尝试移动它时为每个片段创建一个新实例,而是创建所有片段的两个塞特(黑色和白色)。让电路板存储对块的引用,以便您可以直接从板中检索块的实例。
从抽象基类 Piece 派生出实现抽象方法 canMove() 的 Pawns 和其他字符
您可以将enum
用作Piece
工厂。这样你就不需要1 means Pawn, ...
等,因为你有Pieces.Pawn
等。请注意,您仍然可以有一个名为 Pawn
AND 的enum
class
名为 Pawn
,没有歧义。
private abstract static class Piece {
// Current position.
protected int x, y;
// Returns true if this piece could move there.
abstract boolean canMove ( int x, int y);
}
private static class Pawn extends Piece {
@Override
boolean canMove (int toX, int toY) {
// Not handling en-passant and first-move etc.
return toX == x && (toY == y + 1 || toY == y + 2);
}
}
private static class Rook extends Piece {
@Override
boolean canMove (int toX, int toY) {
return toX == x || toY == y;
}
}
// A Piece factory.
private static enum Pieces {
Pawn {
@Override
Piece make () {
return new Pawn();
}
},
Rook{
@Override
Piece make () {
return new Rook();
}
};
abstract Piece make();
}
// Make a Piece.
private static Piece makePiece ( Pieces type ) {
return type.make();
}