如果那么其他如果键入分离方法

时间:2016-02-22 08:33:37

标签: java types

我有这样的方法:

import java.math.*;

class Example
{
    public static void main (String[] args) throws java.lang.Exception
    {
        BigDecimal bd = new BigDecimal("1.10900");
        bd = bd.divide(new BigDecimal("27"), BigDecimal.ROUND_HALF_DOWN);
        System.out.println("1.109 / 27 using BigDecimal to five places: " + bd);

        double d = 1.109;
        d = d / 27.0;
        System.out.println("1.109 / 27 using double:                    " + d);
    }
}

我想把这个结构转换成这样的结构:

//in Constant class
MathObject add(MathObject addend){
    if (addend instanceof Constant)
    {
        return new Constant(this.c + addend.c);
    }
    if (addend instanceof Variable)
    {
        return new Sum(this, addend);
    }
    //...
}

这样,每个对象的正确方法将以更结构化的方式找到,更重要的是实际的返回类型是已知的。 问题是,对于某些情况,例如添加//in Constant class Constant add(Constant addend){ return new Constant(this.c + addend.c); } Addition add(Variable addend){ return new Sum(this, addend); } //... Product,不知道返回的对象是Variable还是Addition,就像这样:

Product

我遇到的问题是,当我在//in Variable class MathObject add(Product addend){ if (addend.contains(this)) { //code return new Product(newArray); } else { return new Sum(this, addend); } } 上使用此类特定操作(即add(Constant),而不是new Sum(constant, variable))时,Java会将其声明的类型视为比它的实际类型,抛出如下错误:MathObject,总结所有操作方法并说no suitable method found for...不在其中。

澄清MathObjectConstant以及此处使用的所有其他对象自然延伸VariableMathObject是一种查找contains(Variable variable)是否已包含Product的方法。

我的想法是能够做到这样的事情:

Variable

这里乘法和第一个添加操作将使用特定于类型的方法,但第二个将失败,因为第一个将返回new Constant(2).multiply(new Variable(1)).add(new Variable(1)).add(new Constant(1)); 而不是特定对象,Java不检查实际类型方法选择。

这些是不同类的外观:

MathObject

我有什么遗失的吗?或者这是一种不好的做法(当然有什么好处)?这甚至可能还是我注定了丑陋的//These are all in different files, silly formatting doesn't allow me to split code sections. public class Constant extends MathObject{ public final double c; public Constant(double c){ this.c = c; } //methods } public class Variable extends MathObject{ public double v; public Variable(double v){ this.v = v; } //methods } public class Sum extends MathObject{ public MathObject summands; public Addition(MathObject... summands){ this.summands = summands; } //methods } 语句链?

1 个答案:

答案 0 :(得分:0)

问题是你有错误的抽象。你需要像

这样的课程
public interface NumberExpr {
  NumberExpr apply();
  Number get();
}

public class Constant implements NumberExpr {
  final Number val;
}

public class Variable implements NumberExpr {
  final Map<String, Number> symbols;
  final String symbolName;
}

public class Addition implements NumberExpr {
  final NumberExpression op1;
  final NumberExpression op2;
}

目前尚不清楚您是否需要一元和三元运算符,但只考虑最简单的二元运算:

+ op1 op2
- op1 op2
* op1 op2
/ op1 op2

也许你有评估odrder,precedence和associativity的规则,无论如何你最终会得到类似的东西:

new Multiplication(
    new Addition(new Variable("counter", ctx), new Variable("i", ctx))
  , new Constant(Math.PI)
)

也许您首先需要迈向.evaluate()表达式,然后.apply(),无论如何,只需在最终结果上调用.apply()然后.get()即可获得最终结果。