假设我想有一个这样的抽象类:
public abstract Operator {
public int[] operands;
public Operator(int[] operands) {
this.operands = operands;
}
public abstract int getOperatorResult();
}
和一些从它扩展的运算符,如:
public class Add extends Operator {
public Add(int[] operands) {
super(operands);
}
public int getOperatorResult() {
return operands[0] + operands[1];
}
}
和一个OperatorCreator,它获得一个表达式,如"1+1",并返回相应的操作符的子类(在本例中为Add):
public class OperatorCreator {
public static Operator getInstance(String expr) {
...
}
}
主要问题:我想让其他人通过扩展Operator类来设计他们自己的运算符。并且多态地使用它们的算子。像这样:
public class Main {
public static void main(String[] args) {
Operator op = OperatorCreator.getInstance("1-2");
System.out.println(op.getOperatorResult());
}
}
假设OperatorCreator知道Operator子类的.class文件的位置,并在运行时使用反射来加载这些子类。但是OperatorCreator还必须知道一件事:它还必须知道这些子类返回一个Add对象的操作符符号,例如当给出"1+1"时。因此,任何操作符的子类都可以有一个静态方法:"getSymbol",它返回操作符的符号。但是有一个问题。如果有人扩展了Operator,但没有提供"静态getSymbol",那么他的代码将在没有为OperatorCreator提供知道新Operator子类的符号的机制的情况下成功编译,这将导致运行时问题。我不想让getSymbol成为Operator的一个抽象方法来强制子类实现它因为我不想为了获得它的符号而创建一个子类的实例。我怎么能强迫子类注册他们的符号时,他们正在加载?
您可以扩展Operator
类层次结构,使其具有每个符号类型的抽象子类,例如AddOperator
, SubtractOperator
, MultiplyOperator
。现在,客户端通过选择要扩展的超类为您提供操作符的类型。