运算符的设计要求是开放的,这几乎立即意味着它必须是抽象的。我一度犹豫运算符是作为接口还是抽象类定义,最后我选择的是抽象类。
public abstract class Operator
{
private String name;
protected Operator(String name) {
this.name = name;
}
public abstract int getDimension();
public abstract Number eva l(Number[] oprands, int offset);
// throws ArithmeticException
public Number eva l(Number[] oprands) {
}
public String toString() {
return name;
}
}
这个运算符的设计包含二个主接口方法。通过getDimention()接口它传达这么一个信息:运算符是几元的?即需要几个操作数。显然,最常见的是一元和二元运算符。这个接口方法似乎也意味着允许有多于二元的运算符,但是对于多于二元的运算符我没有作更深入的考察。我不能十分确定基于栈的表达式的转换和计算算法是否完全支持二元以上的运算符。尽管有这么一点担忧,我还是保留目前的接口方法。
运算符最主要的接口方法就是eva l(),这是运算符的计算接口,反映了运算符的本质。在这个接口方法中要把所有需要的操作数传给它,运算符是几元的,就需要几个操作数,这应该是一致的。然后,执行符合运算符含义的计算,返回结果。如果增加新的运算符,用户需要实现运算符的上述接口方法。
变量
从某种意义上说,变量就是"待定的数值"。我是否应该设计一个Variable类(或接口)?我的确这样做了。变量什么时候,被什么具体数值替代,这些过程我不知道,应该留给用户来处理。我对于变量的知识几乎是零,因此Variable类的意义就不大了。如果继续保留这个类/接口,还给用户带来一个限制,他/她必须继承或实现Varibale类/接口,因此不久