简体   繁体   中英

polymorphism in java chess game

I am new to java and am trying to build the logic to run a chess game. I have a superclass called 'Piece' and subclasses for king, knight, queen etc. I am trying to implement a move method where I determine the type of piece on the fly and then call that piece's corresponding move method. For example:

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);

Is there a way that I can ensure the canMove method will be called by the correct type of piece in this example?

Thanks

If your board would hold Piece objects instead of int values then you could just do:

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

The Piece class would define a canMove method and all its subclasses would implement using their own Strategy.

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

如果您的子类覆盖超类'Piece'上的canMove方法,则myPiece.canMove(endX,endY)就足够了。基于myPiece引用指向的对象类型,jvm将在运行时决定应调用哪种方法。动态方法分派

What I would do would be to create an abstract class or interface denoting the behaviour and properties of a Piece object.

I would then have classes which implement/extend the piece class, each denoting their own behaviour with a canMove method.

You instantiate your objects and then, in your code, you simply get the Piece object residing at position (x, y) and call canMove . This will delegate the behaviour to the appropriate subclass, leaving your code cleaner, more maintainable and flexible.

Having an abstract class or interface, as opposed to having a concrete class for your Piece object, is (in my opinion) advantages since it forces each piece to implement such behaviour, rather than simply inherit it.

You could use an enum as a Piece factory. That way you avoid the need for 1 means Pawn, ... etc because you have Pieces.Pawn etc. Note that you can still have an enum called Pawn AND a class called Pawn with no ambiguities.

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();
}

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

What you did in your question is not really making use of the polymorphism as you are deciding the type of the piece by your program code.

I suggest you change your Desing a bit: Instead of creating a new instance for each piece everytime you try to move it, create two seets of all pieces (black and white). Let the board store the references to the pieces so you can retrieve the instance of the piece directly from the board.

From the abstract base class Piece derrive Pawns and other characters that implement the abstract method canMove()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM