我有一个运算符类,其中包含一些处理数学运算的类和方法。运算符类是通用的并且扩展了Number,所以我的操作可以是int,double,float等。
public class OperatorClass<T extends Number>
在这个类中有一个抽象类,它提供了一种使用calculate方法
操作数字的方法abstract class Op<T extends Number> {
abstract T calculate(DataSet<? extends Number> ds);
}
有多个类像AddOp一样扩展Op,例如:
class AddOp<T extends Number> extends Op<T>{
public T calculate(DataSet<? extends Number> ds) {
return ds.getLeft() + ds.getRight();
}
}
我的DataSet只是一个如下所示的数据类:
public class DataSet<T extends Number> {
private T left;
private T right;
public DataSet(T left, T right) {
this.left = left;
this.right = right;
}
public T getLeft() {
return left;
}
public T getRight() {
return right;
}
}
我遇到的问题是行ds.getLeft() + ds.getRight()
没有编译,因为Number抽象类不能执行+运算符。我如何让我的DataSet成为一种Number(就像一个通配符类),所以我可以对它进行数学运算。
任何帮助将不胜感激 感谢
修改
问题的解决方法是我使用了一些if语句然后得到了正确的原始数据类型
Number result = null;
if(ds.getLeft().getClass().equals(Integer.class))
result = new Integer(ds.getLeft().intValue() + ds.getRight().intValue());
....
return (T) result;
答案 0 :(得分:1)
您必须决定要添加的分辨率。换句话说,您是在呼叫left.getInteger()
还是left.getFloat()
?
有很多方法可以解决这个问题,但它实际上归结为你打算做什么。如果您希望您的数字真正保留为对象,则不能使用+
plus运算符,因为它不适用于对象。您需要left.plus(right)
样式方法调用,该方法将返回一个新数字。
如果你不关心在数学练习期间将你的数字保存为对象(可能它们只是为了收集存储或其他东西),那么你将public T getLeft()
替换为public long getLeft()
并依赖在内部编号left.getLongValue()
上进行转换。或者您只是展示两个Number
对象,并允许“外部”用户执行相应的getXxxValue()
调用。
答案 1 :(得分:0)
数字类型是基本类型,您不能通过它们实现算术运算。 Java的泛型不像C ++模板那样工作,也不生成特定于类型的代码,并且无法添加两个Number实例或任何其他原始包装类型的实例。
您在Java中尝试做的事情是不可能的,您必须为int
,doubles
等编写单独的方法(或者您想要支持的任何方法。)
答案 2 :(得分:0)
不能在Java中重载运算符。最简单的是改变:
return ds.getLeft() + ds.getRight();
to(类似)
return ds.getLeft().getDouble() + ds.getRight().getDouble();
我说类似,因为你可能需要处理一点类型的转换。
认为还有其他方法getFloat() getInt()...
我选择了双倍,因为截断不会有任何损失。