【发布时间】:2014-07-14 02:09:28
【问题描述】:
我正在用 Java 编写一个 2048 游戏和自解算器。我最重要的类是Board,它包含主要的游戏功能。出于效率原因,游戏的许多方面都编码在数组中,例如向左或向右移动时每个可能行的转换。在static 初始化块中,我调用static void generateTables(),它会创建一次表。
具有求解能力的板 extend Board 和 implement 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 答案中的想法和看到的建议:
制作
HeuristicBoardabstract和制作两个方法abstract。但是由于某种原因(是的,我已经阅读了原因)您不能使用static abstract方法。如果我使static int heuristic(byte[] row)非静态,我将无法在static void generateHeuristicTable()方法中使用它,它应该在HeuristicBoard类中实现,而不是在子类中(我必须在每个子类,每次只更改一次性的new SubclassOfHeuristicBoard().heuristic(currentRow)。如果我也将此方法设为非静态方法,忽略上面展示的不便,那么我将无法在static初始化块中调用generateHeuristicTable(),从而使以便类的每个新实例都会生成(大)表。创建一个包含静态方法的
HeuristicSolver接口,然后有HeuristicBoardimplementHeuristicSolver,然后是HeuristicBoard的子类。但是,这迫使我提供静态方法的默认实现,我认为这没有意义。只有子类应该被实例化,因为只有它们应该提供启发式实现。此外,类中的其他静态方法引用的静态变量只能在Board类中找到。还有其他可能性,但在使
HeuristicBoard非抽象之后,它们真的会变得更糟。
在我看来,唯一正确的方法是创建HeuristicBoard abstract,但我不知道如何使用static 方法。
编辑:已经指出这两种方法都可以更改为non-static。这样就解决了上面的问题,但是现在我又遇到了一个问题:在非静态AI方法中,为了递归的目的,我复制了板子:HeuristicBoard option = new HeuristicBoard(board)。但是,如果类是抽象的,我就不能这样做。我应该如何创建当前类的实例? (即在EmptySpaceHeuristicBoard类中,当这个方法被继承并执行时,它应该创建一个new EmptySpaceHeuristicBoard()。
【问题讨论】:
-
对于初学者来说,我认为使用静态初始化器是一个糟糕的设计。只需检查表是否为
null。
标签: java oop inheritance static abstract