如何实现一个通用计算器类

3
最近一位教师布置了一个有关整型和浮点型计算器类的编码任务。该任务的要求如下:
public final class Calculator {

    public int add(int augend, int addend) { return augend + addend; }
    public double add(double augend, double addend) { return augend + addend; }

    public int subtract(int minuend, int subtrahend) { return minuend - subtrahend; }
    public double subtract(double minuend, double subtrahend) { return minuend - subtrahend; }

    public int divide(int dividend, int divisor) { return dividend / divisor; }
    public double divide(double dividend, double divisor) { return dividend / divisor; }

    public int multiply(int multiplicand, int multiplier) { return multiplicand * multiplier; }
    public double multiply(double multiplicand, double multiplier) { return multiplicand * multiplier; }
}

我在想,如果使用泛型能否消除功能重复,因为方法在功能上是相同的?

我尝试了几种方法来实现这个目标,最新的方法是将整个类作为泛型,但在对变量应用数学运算时遇到了困难。

public class Calculator<T extends Number> {
    public T add(T augend, T addend) {
        // addition is the same for any number type
        return augend + addend; // "operator '+' cannot be applied to 'T','T'"
    }
    // etc...
}

无论我尝试哪种方法,都会出现错误信息或其变体...有没有更好的方法来解决这个问题?(使用泛型或不使用泛型)

3
取决于计算器的通用性,您希望Animal类能否使用您的Calculator进行add操作? - Naman
2
你可以使用 Double.valueOf(augend.doubleValue() + addend.doubleValue()) - Sharon Ben Asher
@SharonBenAsher 感谢您的建议,不幸的是返回类型不兼容,需要 T,但找到了 Double。理想情况下,函数应该返回与 T 指定的类型匹配的类型 - 不确定是否可能实现。如果方法返回 Double,则 Double.valueOf() 似乎是不必要的。 - Toby
@SharonBenAsher 我不建议在计算器中使用 double。尝试使用类似于 116.0 / 7.0 * 7.0 的东西(这应该返回 116.0,但实际上并不会)。 - Thomas
Number类不支持算术运算,因此如果您想要一些通用的东西,您可能需要定义一个接口,其中包含每个操作的方法,然后为每种数据类型(整数、浮点数等)创建一些实现,并根据定义的接口使计算器通用化。但这并不能消除冗余,只是以不同的结构进行组织。 - user10386912
显示剩余4条评论
2个回答

0

我认为你不能在类型T上应用运算符。因为在编译期间,对于无界类型,它将被对象替换,在有界类型的情况下,它将被第一个边界替换。请参考https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html。在下面的代码中,它将被替换为Number,但Number不能与运算符一起使用。 您可以创建这样的通用接口:

interface Calc<T extends Number>{
   T add(T a, T b);
}

现在创建整数和双精度浮点数的具体类

class IntegerCalc implements Calc<Integer>{
    @Override
    public Integer add(Integer a, Integer b) {
        return a+b;
    }
}

class DoubleCalc implements Calc<Double>{
    @Override
    public Double add(Double a, Double b) {
        return a+b;
    }
}

0

你做得很好!代码简单可靠,干得漂亮。

P.S. 请注意泛型与ObjectIntegerint并不完全相同。如果可以使用简单类型,请尽量避免使用包装器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接