我怎么知道何时使用枚举或子类?

时间:2013-08-17 03:22:45

标签: class enums polymorphism

让我说我正在下棋。拥有Piece()的基类会更有效吗?包含每种类型的子类。

或者,枚举

enum Piece{
King,
Queen,
Knight,
etc;
}

它还让我了解了在改进数据时遇到的一个常见问题。

GameObjects
Piece extends GameObjects

我是否应该停在此处并声明具有各自属性的对象?

Piece King = new Piece("King",5,10); //just made up values, no significance.

或进一步完善它并具有:

King extends Piece

然后以多态方式处理King Pieces:

Piece king = new King("King,5,10);

感谢

3 个答案:

答案 0 :(得分:1)

多态性

这取决于你想要如何构建游戏逻辑,但是在抽象Piece类中定义常见行为(方法)和属性(字段)然后让每个子类型实现抽象可能是有意义的方法(或覆盖默认方法)并根据它们变化的方式设置继承字段的值。也许是这样的:

public abstract class Piece {
    protected int value;
    public int getValue() {
        return value;
    }
    public abstract boolean isValidMove(String move);
    public void move(String move) {
        //common logic here
        doMove(move);
    }
    protected abstract void doMove(String move);
}

public class King extends Piece {
    public King() {
        this.value = 20;
    }
    public boolean isValidMove(String move) {
        //specific king logic here
    }
    protected void doMove(String move) {
        //more specific king logic
    }
}

这将允许您使用多态来定义具有公共Piece API的各个部分,而重要的差异由每个具体类型处理。

Piece king = new King();
//...
if(king.isValidMove(move)) king.move(move);

枚举

Enums允许您创建一组公共类型的优化单例实例,这些实例也可以定义行为,但它们不支持覆盖/实现类型特定的行为,因为您最终必须检查哪个枚举实现变体时的当前实例。当你真的需要一个游戏的倍数(一个白王和一个黑王,8个白色棋子和8个黑色)时,你最终会遇到只有一个KINGPAWN个实例的问题。棋子)。

public enum Piece {
    KING(20),
    PAWN(1);
    private int value;
    private Piece(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    public boolean isValidMove(String move) {
        switch(this) {
            case KING:
                //king specific logic
                break;
            case PAWN:
                //pawn specific logic
                break;
        }
    }
    public void move(String move) {
        if(this == KING) {
            //king specific logic
        } else if(this == PAWN) {
            //pawn specific logic
        }
    }
}

因此,在这种情况下,枚举可能不会很好。

答案 1 :(得分:0)

如果实例存在有限且定义的数字,则使用枚举。

在这种情况下,显然有一定数量的碎片,所以请使用枚举。

请注意,枚举可以像常规类一样使用方法,因此枚举不必仅仅是“值”,它们可以执行操作。

我不会尝试过多地填充你的枚举,事实上我会将它命名为PieceType以明确它代表什么,并且可能有一个类Piece,它是一个实例一件具有PieceType,位置(棋盘方块)和颜色的作品。

答案 2 :(得分:0)

主要区别在于子类集是开放式的:您或其他使用您代码的人可以在不破坏旧代码的情况下创建新的子类。 枚举是相反的:其他人不能在你的枚举中添加新项目,即使你是代码的维护者,也不能在不重复检查每一个switch-case语句的情况下添加新的枚举常量。

因此,如果您不希望将新项目添加到集合中,请使用枚举。否则使用子类。这并不意味着子类更好:如果您知道要封闭的选项集,那么您不应该使用子类。如果你这样做,你会发现自己正在写if (... instanceof ...)链!

如果使用枚举,您会发现自己在case语句中添加了新的switch(或者您可以预料到这一点),然后切换到子类。如果使用子类,您会发现自己编写instanceof个链,然后切换到枚举。