我想要一个像这样的抽象类:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
<div class="draggable">hi!</div>
<div id="mydiv"></div>
<div id="mydiv_second"></div>
并且有些运营商会从中扩展出来:
public abstract Operator {
public int[] operands;
public Operator(int[] operands) {
this.operands = operands;
}
public abstract int getOperatorResult();
}
一个OperatorCreator获取类似“1 + 1”的表达式并返回相应的Operator子类(在本例中为Add):
public class Add extends Operator {
public Add(int[] operands) {
super(operands);
}
public int getOperatorResult() {
return operands[0] + operands[1];
}
}
主要问题: 我希望让其他人通过扩展Operator类来设计自己的运算符。并以多态方式使用其运算符。像这样的东西:
public class OperatorCreator {
public static Operator getInstance(String expr) {
...
}
}
我该怎么做?
编辑: 我知道有可能使用反射。但如果可能的话,我宁愿不使用反射。而且我知道我可以让运算符子类的设计者在运行时调用一个方法来注册她的新类。但我不想使用这种方法。
谢谢!
答案 0 :(得分:3)
基本上你问的是如何实现一个框架;在以下意义上:
如果其他方可以提供实现运营商的类;重点是:您需要一个中心实例,该实例了解哪个类提供了哪个运算符的实现。
因此,一个解决方案是&#34;实施者&#34;必须提供类似&#34; getOperator()&#34;的方法。 ......然后返回&#34; - &#34;或&#34; +&#34;或者其他什么。
然后你可以使用反射来扫描&#34;类文件,如果它们实现了你的接口;如果是这样;你可以打电话给&#34; getOperator()&#34;了解哪个类提供哪个实现。稍后,您的OperationCreator可以使用该知识来实例化那些需要解析的类的对象&#34; 1-2&#34;例如。
我更喜欢避免使用反射的方法。相反,一个&#34;实施者&#34;应该可以调用一些像&#34; OperationCreator.registerOperationProvider()&#34;这样的方法。含义:首先,告诉OperationCreator XYZ可以处理的对象&#34; - &#34 ;;然后,OperationCreator可以调度&#34; - &#34;以后到XYZ。
答案 1 :(得分:2)
如果问题的主要内容是如何在运行时获取实现:这就是ServiceLoader
类的用途。然后,实现者只需要实现抽象类,并放置一个像
META-INF/services/your.packagename.Operator
进入他们的META-INF
文件夹。在此文件中,他们可以列出他们的实现:
their.packagename.MinusOperator
their.packagename.MultiplyOperator
当他们的代码在应用程序的类路径中可见时(例如,当它被打包到添加到类路径的JAR文件中时),那么您可以使用ServiceLoader
轻松列出{的所有实现{1}}课程。 JavaDoc of the ServiceLoader
class包含一个精心设计的示例,说明如何完成此操作,因此我将在此省略其他示例代码(这非常简单)。
如果问题的主要内容是如何使用这些实现,请参考他们可能需要的事实,例如Operator
返回{{} 1}}或getOperatorChar()
,或更广泛地说:如何创建一个自动实例化这些类的解析器,然后它应该重写一点......