设计一个抽象 class 以便任何人都可以扩展它并以多态方式使用扩展的 class
design an abstract class so that any one can extend it and use the extended class polymorphically
我想要一个这样的摘要class:
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”这样的表达式和 returns 适当的 Operator 的子 class(在这种情况下添加):
public class OperatorCreator {
public static Operator getInstance(String expr) {
...
}
}
主要问题:
并且想通过扩展Operatorclass让别人设计自己的算子。并以多态方式使用它们的运算符。像这样:
public class Main {
public static void main(String[] args) {
Operator op = OperatorCreator.getInstance("1-2");
System.out.println(op.getOperatorResult());
}
}
我该怎么做?
编辑:
我知道可以使用反射。但如果可能的话,我宁愿不使用反射。而且我知道我可以让 Operator 的子 class 的设计者在运行时使用调用方法来注册她的新 class。但是我不想用这个方法。
谢谢!
基本上你问的是如何实现一个框架;在以下意义上:
如果其他方可以提供 classes 来实现一个运算符;要点是:你需要一个中央实例来理解哪个 class 为哪个运算符提供实现。
因此,一个解决方案是 "implementer" 必须提供一种方法,例如 "getOperator()" ... 然后 return“-”或“+”或其他.
然后您可以对 "scan" class 文件使用反射,如果它们实现了您的接口;如果是这样;您可以调用 "getOperator()" 来了解哪个 class 提供了哪个实现。稍后,您的 OperationCreator 可以使用该知识来实例化那些 classes 的对象,例如解析“1-2”所需的对象。
我更喜欢避免使用反射的方式。相反,"implementer" 应该能够调用某些方法,例如 "OperationCreator.registerOperationProvider()"。含义:首先,你告诉OperationCreator对象XYZ可以处理“-”;然后 OperationCreator 稍后可以将对“-”的调用分派给 XYZ。
如果问题的重点是如何在运行时获取实现:这就是 ServiceLoader
class 的用途。然后实现者只需实现抽象 class,并放置一个像
这样的文件
META-INF/services/your.packagename.Operator
进入他们的 META-INF
文件夹。在这个文件中,他们可以列出他们的实现:
their.packagename.MinusOperator
their.packagename.MultiplyOperator
当他们的代码在应用程序的 class 路径中可见时(例如,当它被打包在添加到 class 路径的 JAR 文件中时),那么您可以使用 ServiceLoader
轻松列出 Operator
class 的所有实现。 JavaDoc of the ServiceLoader
class 包含一个详尽的示例,说明如何完成此操作,因此我将在此处省略更多示例代码(真的很简单)。
如果问题的重点是如何使用这些实现,指的是他们可能需要的事实,例如,像getOperatorChar()
返回 -
或 *
,或更广泛地说:How to create a parser that automatically instantiates these classes, then it should be rewording a bit...
我想要一个这样的摘要class:
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”这样的表达式和 returns 适当的 Operator 的子 class(在这种情况下添加):
public class OperatorCreator {
public static Operator getInstance(String expr) {
...
}
}
主要问题: 并且想通过扩展Operatorclass让别人设计自己的算子。并以多态方式使用它们的运算符。像这样:
public class Main {
public static void main(String[] args) {
Operator op = OperatorCreator.getInstance("1-2");
System.out.println(op.getOperatorResult());
}
}
我该怎么做?
编辑: 我知道可以使用反射。但如果可能的话,我宁愿不使用反射。而且我知道我可以让 Operator 的子 class 的设计者在运行时使用调用方法来注册她的新 class。但是我不想用这个方法。
谢谢!
基本上你问的是如何实现一个框架;在以下意义上:
如果其他方可以提供 classes 来实现一个运算符;要点是:你需要一个中央实例来理解哪个 class 为哪个运算符提供实现。
因此,一个解决方案是 "implementer" 必须提供一种方法,例如 "getOperator()" ... 然后 return“-”或“+”或其他.
然后您可以对 "scan" class 文件使用反射,如果它们实现了您的接口;如果是这样;您可以调用 "getOperator()" 来了解哪个 class 提供了哪个实现。稍后,您的 OperationCreator 可以使用该知识来实例化那些 classes 的对象,例如解析“1-2”所需的对象。
我更喜欢避免使用反射的方式。相反,"implementer" 应该能够调用某些方法,例如 "OperationCreator.registerOperationProvider()"。含义:首先,你告诉OperationCreator对象XYZ可以处理“-”;然后 OperationCreator 稍后可以将对“-”的调用分派给 XYZ。
如果问题的重点是如何在运行时获取实现:这就是 ServiceLoader
class 的用途。然后实现者只需实现抽象 class,并放置一个像
META-INF/services/your.packagename.Operator
进入他们的 META-INF
文件夹。在这个文件中,他们可以列出他们的实现:
their.packagename.MinusOperator
their.packagename.MultiplyOperator
当他们的代码在应用程序的 class 路径中可见时(例如,当它被打包在添加到 class 路径的 JAR 文件中时),那么您可以使用 ServiceLoader
轻松列出 Operator
class 的所有实现。 JavaDoc of the ServiceLoader
class 包含一个详尽的示例,说明如何完成此操作,因此我将在此处省略更多示例代码(真的很简单)。
如果问题的重点是如何使用这些实现,指的是他们可能需要的事实,例如,像getOperatorChar()
返回 -
或 *
,或更广泛地说:How to create a parser that automatically instantiates these classes, then it should be rewording a bit...