我需要帮助解决我在 Java 中遇到的泛型问题。我正在编写这个计算机代数系统,用户在其中输入数学表达式,系统以不同的方式处理它(扩展它、简化它等)。它适用于包含自然数的表达式,我想扩展它以适用于数学集合。除了 +,您还可以使用交集运算符等。
起初,我开始为场景录制所有内容,但后来我意识到这可能不太好,于是开始使用泛型。
而不是像 MathExpr
这样的解析树还有一个像SetExpr
, 我想我可以有一个通用的 Expression<T>
并构建一个基类 Number
和一个基类 Set
.
为了澄清,我希望像 (2 * a) + (3 + 2) 这样的数学表达式是类 Expression<Number>
的一个实例和一个集合表达式,如 (A ∪ B) ∩ C 是 Expression<Set>
的一个实例.然后我可以对此执行不同的操作,比如计算深度等。
+ 操作作为一个类实现,* 作为一个类等。这两个类都是名为 TwoExpr
的抽象类的子类。这又是抽象类的子类 Expr
.我现在就是这样做的,一切正常。
当我想更改我的代码时,我创建了 Expr
类泛型。即Expr<T>
.我还将 TwoExpr 更改为 TwoExpr<T>
并创建了一个基类 Number
.
问题是,现在我似乎无法实例化 Sum<Number>
类型的对象.
我收到“Type mismatch: cannot convert from Sum to Expr<Number>
”错误。但是Sum
是 TwoExpr<Number>
的子类,它又是 Expr<Number>
的子类.正如您可能意识到的,我无法上课 Sum
通用并称之为Sum<Number>
,因为所有算术运算都没有集合的类似物。
我一直能够创建像这样的对象
Expr zero= new Leaf(0);
Variable a = new Variable("a");
Expr aPlusZero = new Sum(a, zero);
当我改成泛型时,同样的代码看起来是这样的:
Expr<Number> zero= new Leaf<Number>(new Number(0)); //works fine
Variable<Number> a = new Variable<Number>("a"); //works fine
Expr<Number> APlusZero=new Sum(a,zero); //gives a "Type mismatch:
//cannot convert from Sum to Expr<Number>" error
为什么它不识别 Sum(a,zero)
是 Expr<Number>
的子类,当它在 Sum 的声明中说时
public class Sum extends TwoExpr<Number> {
public Sum(Expr<Number> a, Expr<Number> b) {
super(a, b);
}
...
}
在 TwoExpr 的声明中
public abstract class TwoExpr<T> extends Expr<T> {
protected Expr<T> a;
protected Expr<T> b;
public TwoExpr(Expr<T> a, Expr<T> b) {
this.a=a;
this.b=b;
}
...
}
我知道 Lizkows 替换原则不适用于泛型参数。但是 Number 不是任何东西的子类(Object 除外)并且没有任何子类。 我希望我已经相当清楚我正在尝试做什么以及我遇到了什么问题。有人知道如何解决吗?如果上面有任何不清楚的地方或者您需要更多代码,请告诉我。
提前致谢。
马蒂亚斯
最佳答案
我认为您的问题出在您未显示的类(class)中,我尝试了以下方法并且有效:
Expr<Number> zero= new Expr<Number>();
Expr<Number> a= new Expr<Number>();
Expr<Number> APlusZero=new Sum(a,zero);
可能是 Variable 不是 Expr?
更新:
我按照自己的想象创建了 Variable 和 Leaf,一切正常:
public class Number {
public Number(int i){}
}
public class Variable<T> extends Expr<T> {
public Variable(String s){}
}
public class Leaf<T> extends Expr<T> {
public Leaf(T t) {
super();
}
}
public class Expr<T> {
}
public class TwoExpr<T> extends Expr<T> {
public TwoExpr(Expr<T> a, Expr<T> b) {
}
}
public class Sum extends TwoExpr<Number> {
public Sum(Expr<Number> a, Expr<Number> b) {
super(a, b);
}
}
public class AllTogether {
public static void main(String[] args) {
Expr<Number> zero= new Leaf<Number>(new Number(0));
Variable<Number> a = new Variable<Number>("a");
Expr<Number> APlusZero=new Sum(a,zero);
}
}
如果您从 Variable 中获取 extends Expr,它确实会给出您遇到的错误,这可能是原因吗?
关于Java 子类无法识别其泛型父类(super class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5384808/