适当的Java继承结构

时间:2014-05-25 00:13:24

标签: java oop inheritance static abstract

我正在用Java编写2048游戏和自解算器。我最重要的课程是Board,其中包含主要的游戏功能。出于效率原因,游戏的许多方面都以数组编码,例如当向左或向右移动时每个可能行的变换。在static初始化块中,我调用static void generateTables(),它会创建一次表。

具有求解功能extend Boardimplement Solver的论坛,包含使用高级方法getDirection()getWorstLocation()的界面通过接口类来运行解算器并获取提示。我感兴趣的主要解算器类型记录了所有可能行的启发式值列表,然后使用这些值运行expectiminimax搜索。所以我有课:

public class HeuristicBoard extends Board implements Solver {

    private static int[] heuristic; // Lookup table

    /* ... methods omitted ... */

    private int heuristic() {...}
    // Calculates a heuristic value for the entire board based
    // on calls to the following method
    // This method's code could change depending on algorithm implementation.
    private static int heuristic(short row) {...}
    // Checks the lookup table for the row provided
    private static void generateHeuristicTable() {...}
    // Generates the lookup table based on calls to the following method
    private static int heuristic(byte[] row) {...}
    // Calculates the heuristic value for a single row.
    // This method's code could change depending on algorithm implementation.
}

现在,我想测试多种不同的启发式方法,但使用相同的expectiminimax算法。因此,int heuristic()static int heuristic(byte[] row)的实现会发生变化,而其他实现则会保持不变。抽象HeuristicBoard类的功能以便有多个实现int heuristic()static int heuristic(byte[] row)的子(?)类的最佳方法是什么?他们最好有一个共同的祖先,所以我可以:

ClassOrInterface firstSolver = new EmptySpaceHeuristicBoard();
ClassOrInterface secondSolver = new MonotonicityHeuristicBoard();

我已经想到并在各种StackOverflow答案中看到了建议:

  1. 制作HeuristicBoard abstract并制作两种方法abstract。但出于某种原因(是的,我已经阅读了原因)你不能拥有static abstract方法。如果我使static int heuristic(byte[] row)非静态,我将无法在static void generateHeuristicTable()方法中使用它,这应该在HeuristicBoard类中实现,而不是在子类中实现(我会在每个子类中重新实现它,每次只更改一次性new SubclassOfHeuristicBoard().heuristic(currentRow)。如果我也使这个方法非静态,忽略上面所示的不便,那么我将无法调用generateHeuristicTable()static初始化块中,从而使得每个新的类实例都会生成(大)表。

  2. 创建一个包含静态方法的HeuristicSolver接口,然后HeuristicBoard implement HeuristicSolver,然后继承HeuristicBoard。但是,这迫使我提供静态方法的默认实现,我认为这没有道理。只应该实例化子类,因为只有它们应该提供启发式实现。此外,类中的其他静态方法仅引用Board类中的静态变量。

  3. 还有其他可能性,但在使HeuristicBoard非抽象后,它们真的会变得更糟。

  4. 在我看来,唯一正确的方法是制作HeuristicBoard abstract,但我无法弄清楚如何使用static方法。

    编辑:已经指出两种方法都可以更改为non-static。这解决了上述问题,但现在我有另一个问题:在非静态AI方法中,我复制了板以用于递归目的:HeuristicBoard option = new HeuristicBoard(board)。但是,如果这个类是抽象的,我就不能这样做。我应该如何创建当前类的实例? (即在EmptySpaceHeuristicBoard类中,当继承并执行此方法时,它应创建new EmptySpaceHeuristicBoard()

1 个答案:

答案 0 :(得分:0)

有几点意见:

  1. 静态方法总是可以实现为不使用任何实例变量的实例方法,这样就可以解决您的问题而无法覆盖静态方法。

  2. 我不明白为什么启发式板会扩展板。我认为让一个像scoreBoard()这样的方法的Solver类更有意义。

  3. 2048不是一个极小极大的游戏,因为对手'没有选择' min'选项,而是随机选项。因此,要使用的优化器是expectimax。