我正在制作一个国际象棋游戏,我有一个基本的“片段”界面,我希望所有的部分都能实现。我有一些常见的变量,每个都需要,但我不想在每个类中创建getter和setter(看起来它反对DRY)。
我所做的就是我的界面PieceBase,有一个名为Piece的具体类,我从Piece获得了我的实际部分,并实现了PieceBase。我不希望片段被实例化,因为它本身没有意义,而且这种方法的一些让我感到不安。
这通常是怎么做的?
具体来说,这是用Java编写的,但我不知道它是否与其他任何OO语言不同。
答案 0 :(得分:2)
至少在Java和C ++中,通常认为使用继承来实现代码重用是不好的做法(参见Joshua Bloch的“Effective Java”参数)。通常最好使用组合(或其他形式的委托)。
在你的情况下,我会完全扭转局面,这样Piece
就是final class
只需要enum
来表示它的类型:
public final class Piece {
public static enum Type {
PAWN {
List<Move> getLegalMoves(Color c, Location l) { /* ... */ }
},
BISHOP { /* ... */ },
KNIGHT { /* ... */ },
ROOK { /* ... */ },
QUEEN { /* ... */ },
KING { /* ... */ }; // i hope i didn't forget anything :P
abstract List<Move> getLegalMoves(Color c, Location l);
// ... etc.
}
private final Type type;
private final Color color;
private Location location;
public Piece(Type type, Color color, Location location) {
this.type = type;
this.color = color;
this.location = location;
}
public List<Move> getLegalMoves() {
return type.getLegalMoves(color, location);
}
// ... etc.
}
因此,所有部分中共有的所有逻辑都在Piece
中实现一次,而不同的部分由Type
封装。如果你需要知道你正在看什么样的作品,你不需要使用instanceof
和演员或任何东西,你只需要实现Piece.getType()
和switch
答案 1 :(得分:1)
你想扩展Piece和Implement PieceBase似乎很奇怪......但也许我没有看到什么。如果您使用了一个接口,那么实现它的所有类仍然需要定义自己的getter / setter。
创建一个抽象类似乎有意义吗?
这样他们都使用相同的getter / setter ....如果这是你想要完成的。
答案 2 :(得分:0)
在这种情况下,我没有看到界面的值。我建议简单地使用所需的公共getter和setter来定义抽象类Piece,然后让你的具体类扩展为Piece。
abstract class Piece { ... common stuff ...}
class Pawn extends Piece { ... pawn-specific stuff ... }
class Knight extends Piece { ... knight-specific stuff ... }
...