从特定的表达式树到通用的单java

从特定的表达式树到通用的单java,java,generics,Java,Generics,我想写一个抽象类“Expression”,它接受整数或布尔表达式,并通过子类对它们求值,比如整数的“Add”、“Divide”和布尔表达式的“and”、“or”。最后,它归结为编写实现自己的evaluate()方法的子类。我在一本书中找到了一个实现,但它只适用于双值。这是: abstract class Expr { abstract double eval(); } abstract class BinOp extends Expr { Expr left; Expr

我想写一个抽象类“Expression”,它接受整数或布尔表达式,并通过子类对它们求值,比如整数的“Add”、“Divide”和布尔表达式的“and”、“or”。最后,它归结为编写实现自己的evaluate()方法的子类。我在一本书中找到了一个实现,但它只适用于双值。这是:

abstract class Expr {
    abstract double eval();
}
abstract class BinOp extends Expr {
    Expr left;
    Expr right;
    BinOp(Expr l, Expr r) {
    }
}
class Const extends Expr {
    private double value;
    Const( double val ) {
        this.value = val;
    }
    double eval () {
        return this.value;
    }//eval
}
现在,对于BinOp类,我可以编写一个类'Add',对其进行扩展,调用其构造函数,并通过两个常量对象的乘法实现eval(),这些常量对象本身eval()并简单地返回它们实例化时使用的值

如果我想使用Expr,而不是严格地将计算值绑定为double,而是int或boolean,这将如何工作?我已经阅读了泛型,但我似乎无法正确地设计像Expr这样的类,以便我的代码能够编译。以下是我的尝试:

public abstract class Expression<T> {
    abstract T evaluate();
}
public class Const<T> extends Expression{
    private T n;
    public Const(T x) { n = x; }
    public Const<Integer> integerConst(Integer n) {
        return new Const<>(n);
    }
    public Const<Boolean> booleanConstConst(Boolean n) {
        return new Const<>(n);
    }
    public T evaluate() {
        return n;
    }
}
公共抽象类表达式{
抽象T评估();
}
公共类Const扩展了表达式{
私人电话;
公共常数(tx){n=x;}
公共常量整数Const(整数n){
返回新常量(n);
}
公共常量布尔常量(布尔n){
返回新常量(n);
}
公营部门评估(){
返回n;
}
}

现在我不想让任何人帮我做家庭作业,所以我只是问我的方法的错误在哪里,是否有人能给我指出正确的方向。谢谢。

以下是一些建议:

  • 首先,您不应该使用原始类型,因此
    Const
    应该扩展
    Expression

  • 现在,您的
    integerConst
    booleanconst
    方法看起来像工厂方法,因此它们应该是
    静态的

  • 也就是说,我不确定将这些工厂方法放在
    Const
    类中是否是一个好主意,因为如果您想支持第三种表达式类型(除了
    Boolean
    Integer
    ),它将迫使您更改
    Const
    类型。相反,您可能需要考虑子类<代码> const >:

    public class IntegerConst extends Const<Integer> {
        public IntegerConst(Integer n) {
            super(n);
        }
    }
    
    public class BooleanConst extends Const<Boolean> {
        public BooleanConst(Boolean b) {
            super(b);
        }
    }
    
    公共类IntegerConst扩展常量{
    公共整数const(整数n){
    超级(n);
    }
    }
    公共类BooleanConst扩展了Const{
    公共布尔常量(布尔b){
    超级(b);
    }
    }
    

希望您可以从这里继续。

我认为您应该将所有逻辑隐藏在
表达式之后,并且所有特定于类型的逻辑都应该在单独的类中

要隐藏具体实现,应为每个具体实现使用参数化的
表达式
类和工厂方法

public interface Expression<T> {

    T evaluate();

    static BooleanExpression with(boolean val) {
        return new BooleanExpression(val);
    }

    static DoubleExpression with(double val) {
        return new DoubleExpression(val);
    }

}
客户端代码显示所有具体实现都是隐藏的,并且每个表达式只有可接受的运算符:

boolean res1 = Expression.with(false).and(true).or(true).evaluate();   // true
double res2 = Expression.with(0.5).add(2.5).divide(2).evaluate();       // 1.5

非常感谢,我会尽力的。
public final class DoubleExpression implements Expression<Double> {

    private final double left;

    public DoubleExpression(double left) {
        this.left = left;
    }

    public DoubleExpression add(double right) {
        return new DoubleExpression(left + right);
    }

    public DoubleExpression divide(double right) {
        return new DoubleExpression(left / right);
    }

    @Override
    public Double evaluate() {
        return left;
    }
}
boolean res1 = Expression.with(false).and(true).or(true).evaluate();   // true
double res2 = Expression.with(0.5).add(2.5).divide(2).evaluate();       // 1.5