1

我是 java 新手,正在尝试构建运行国际象棋游戏的逻辑。我有一个名为“棋子”的超类和国王、骑士、王后等的子类。我正在尝试实现一个移动方法,在该方法中我动态确定棋子的类型,然后调用该棋子的相应移动方法。例如:

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 方法被正确类型的片断调用?

谢谢

4

7 回答 7

4

如果您的董事会将持有Piece对象而不是int值,那么您可以这样做:

Piece piece = _board[x][y];
piece.canMove(...);

该类Piece将定义一个canMove方法,其所有子类将使用它们自己的策略来实现。

于 2013-01-24T13:27:07.657 回答
3

在所有子类中重写canMove并在父类中使其抽象Piece

于 2013-01-24T13:26:35.953 回答
0

您可以将 anenum用作Piece工厂。这样你就可以避免需要1 means Pawn, ...etc,因为你有Pieces.Pawnetc。请注意,你仍然可以有一个enum被调用Pawn和一个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();
}
于 2013-01-24T13:31:51.287 回答
0

您在问题中所做的并不是真正利用多态性,因为您正在通过程序代码决定片段的类型。

我建议您稍微更改一下您的设计:不要在每次尝试移动它时为每个部分创建一个新实例,而是为所有部分(黑色和白色)创建两个集合。让棋盘存储对棋子的引用,以便您可以直接从棋盘检索棋子的实例。

从抽象基类 Piece 派生 Pawns 和其他实现抽象方法 canMove() 的角色

于 2013-01-24T13:37:18.563 回答
0

我要做的是创建一个抽象类或接口来表示Piece对象的行为和属性。

然后,我将拥有实现/扩展片段类的类,每个类都用一个canMove方法表示它们自己的行为。

您实例化您的对象,然后在您的代码中,您只需获取Piece位于 (x, y) 位置的对象并调用canMove. 这会将行为委托给适当的子类,使您的代码更简洁、更易于维护和更灵活。

拥有一个抽象类或接口,而不是为您的Piece对象拥有一个具体类,是(在我看来)优势,因为它强制每个部分实现这种行为,而不是简单地继承它。

于 2013-01-24T13:28:36.323 回答
0

如果您的子类覆盖超类 'Piece' 上的 canMove 方法,myPiece.canMove(endX, endY) 就足够了。根据 myPiece 引用指向的对象类型,在运行时 jvm 将决定它应该调用哪个方法。这被称为动态方法分派

于 2013-01-24T13:28:04.463 回答
0

我建议您使用Enum实现抽象类 Piece 而不是 int 的二维数组来表示板,Example 。您可以通过这样做来避免幻数。

于 2013-01-24T13:36:24.597 回答