我正在使用 Java(一个 Swing 应用程序)进行机器人模拟。我有一个抽象类“机器人”,从中派生出不同类型的机器人,例如
public class StupidRobot extends Robot {
int m_stupidness;
int m_insanityLevel;
...
}
public class AngryRobot extends Robot {
float m_aggression;
...
}
如您所见,每个 Robot 子类都有一组不同的参数。
我想做的是在初始 UI 中控制模拟设置。选择机器人的数量和类型,为其命名,填写参数等。
这是一个像恐龙一样的程序员,而且是 Java 的新手,我想知道是否有一些更高层次的东西/想法可以帮助我。所以这就是我得到的:
(1) 用户界面
左侧机器人类型的滚动列表。 中间的“添加>>”和“<<删除”按钮。 右侧机器人的默认命名滚动列表。 下方的“设置参数”按钮。 (因此,如果您想要一个 AngryRobot,您可以在左侧列表中选择 AngryRobot,单击“添加>>”,然后“AngryRobot1”将显示在右侧。)
在右侧选择机器人时,单击“设置参数...”按钮,这将调用另一个模型对话框,您可以在其中填写参数。每个调用不同的对话框 机器人类型。
(2) 数据结构与实现
作为最终产品,我认为 HashMap 最方便。键是机器人类型,伴随的对象是所有参数。初始化程序可以只一次检索每个项目并实例化。数据结构如下所示:
enum ROBOT_TYPE {STUPID, ANGRY, etc}
public class RobotInitializer {
public ROBOT_TYPE m_type;
public string m_name;
public int[] m_int_params;
public float[] m_float_params;
etc.
初始化器的构造函数将根据类型创建适当长度的参数数组:
public RobotInitializer(ROBOT_TYPE type, int[] int_array, float[] float_array, etc){
switch (type){
case STUPID:
m_int_params = new int[STUPID_INT_PARAM_LENGTH];
System.arraycopy(int_array,0,m_int_params,0,STUPID_INT_PARAM_LENGTH);
etc.
一旦所有 RobotInitializer 都被实例化,它们就会被添加到 HashMap 中。
遍历 HashMap,模拟初始化程序从 Hashmap 中获取项目并实例化适当的机器人。
这合理吗?如果不是,如何改进?
谢谢
最佳答案
您可以使用反射在运行时动态加载类型。参见 Class.forName
看看如何获得一个 Class
给定的完全限定名称。然后您可以使用 isAssignableFrom 方法来检查该类是否是 Robot 的子类。您可以在 Robot 中定义一些模板方法,让子类指定具体的行为(例如,应该初始化哪些属性)。获得类定义后,您可以使用 newInstance()
方法创建 Robot 的实例(该类必须具有默认构造函数,否则您应该使用 getConstructors()
方法并使用你想要的那个)。
我知道还有另一种加载类定义的方法,它给出了类文件的完整路径,但现在不记得是怎么做的了。
关于Java 在运行时加载用户指定的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2898362/