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