如何将Java泛型应用于计算器?

时间:2011-10-15 22:42:03

标签: java generics calculator

我正在做作业。

首先,有一个计算器的任务,可以评估这样的表达式:5 *(2 + 1)。

现在,我有了新任务。根据输入参数,表达式必须以不同类型(Integer,Double,Long,Float)计算。我应该使用泛型。

问题是我无法理解如何在程序结构中实现它。现在,我将简要介绍一下。

类标记 {char kind,double value} - 包含标记。

Class TokenStream - 将表达式拆分为标记。

Class Parser - 构建一个解析树,并以反向波兰表示法保存令牌

课程评估员 - 评估RPN

Class Calc - 包含主要功能

老师建议使用:

interface Operation<E> {
    E parse(String)
    E add(E e1, E e2)
    ...
}
IntOperation implements Operation<Integer> {...}

我不明白该怎么做以及他的意思是什么。你能建议吗?

PS:对不起我的英文:)

1 个答案:

答案 0 :(得分:5)

你的主要问题是你正在使用像对象的int,long,double等原始类型。当您使用Generics时,第一条规则要记住,泛型仅适用于对象类型。在这种情况下,将是整数,长,双等。

重要信息四,您的情况是,Java中的所有数字对象都应该扩展Number类。当我们知道这一点时,解决方案的图片就会开始出现。

public abstract interface Operation<T extends Number> {
   T parse(String expression);
   T add(T number1, T number2)

}

然后,将实现此接口的类将处理所有数字类型。

例如对于Long.class,实现如下:

public final OperationForLong implements Operation<Long> {

      @Override
      Long parse(String expression) {

       // code omitted 
    }

    @Override
    Long add(Long number1, Long number2) {
       // code omitted 

    }

}

PS。我用过你的界面设计。但我认为解析和计算的逻辑应该是分开的。这意味着相反,有一个接口执行解析操作并计算结果。你应该有两个接口用于解析,第二个接口用于计算。例如,您可以在将来只传递数字,而不包含带表达式的字符串。

所以设计理念:

public abstract interface MathExpressionParser {

      public Calculation parse(String expression);

}

public abstract interface Calc<T extends Number> { 

   public abstract T add(T num1, T num2);
   public abstract T substract(T num1, T num2);
   public abstract T multiple(T num1, T num2);
   public abstract T divide(T num1, T num2);

}

示例实现:

 public RPNCalculation implements MathExpressionParser {

      public Calculation parse(String expression) {

            // do to parse 
       }

}


public SimpleCalc implements Calc<Number> {

    public Number add(Number num1,Number num2) {

         if(num1 == null || num2 == null) {

            throw new InvalidArgumentExpression("Method Calc.add operate only on non null valuers.");
         }

      return Double.parse(num1.doubleValue() + num2.doubleValue());

    }

}