由于类型不兼容,下面的代码无法编译。然而,我正在尝试做一些类似的事情。据我所知,为了让这个工作,我必须采取超类,检查它是什么类型,并使用切换情况或一个讨厌的if else设置。我可以在这里利用多态性,并将访问方法放在ASTNode中,并在每个子类中重写它,但是,当我想确保这保留在解释器类中时,这是将逻辑放在ASTNode类中。
public class Test {
private class ASTNode{
}
private class ExprNode extends ASTNode{
}
private class VarNode extends ASTNode{
}
private class Interpreter{
public Interpreter(ASTNode node){
this.visit(node);
}
public void visit(ExprNode node){
}
public void visit(VarNode node){
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
ASTNode node = new ExprNode();
Interpreter interpreter = new Interpreter(node);
}
}
我正在构建一个解释器,我正在使用解释器的访问者模式。每种类型的节点都有一种访问方法。在我用python编写的示例中,它们使用getattr方法,该方法根据子类将调用分派到正确的方法。我不知道Java中有任何类似的东西。
最后,如果我在这里使用多态性,我将在ASTNode类中为解释器和赛门铁克分析器定义不同的访问方法。我喜欢在解释器类中有解释器逻辑的想法,但我讨厌基于子类类型有一个巨大的切换案例。
有什么想法吗?也许我错过了一个简单的技巧。
访问器模式的要点是通过处理单个子类上的访问器调用,用多态性代替"大开关"。这并不意味着逻辑包含在子类中,而是在访问者类上定义的。下面是在您的示例中的样子:
interface NodeVisitor {
void visit(ExprNode node);
void visit(VarNode node);
}
class Interpreter implements NodeVisitor {
@Override
public void visit(ExprNode node) {
// custom logic here
}
@Override
public void visit(VarNode node) {
// custom logic here
}
}
private class ASTNode {
public abstract void accept(NodeVisitor visitor);
}
private class ExprNode extends ASTNode {
@Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
}
private class VarNode extends ASTNode {
@Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
}
public static void main(String[] args) {
ASTNode node = new ExprNode();
node.accept(new Interpreter());
}