我正在开发一个培训课程,该课程有一个Training类,其函数返回一个随机方法(一种练习类型)。
这个泛型类由一些特定的类扩展,包含不同类型的练习。
然后我创建一个特定类的数组,并想要选择一个随机类,然后调用随机运动方法。
这是通用类
public class TrainingClasses {
Method[] mMethods;
Random randomGenerator;
public void TraningClasses() {
randomGenerator = new Random();
/* Store methods */
mMethods= getClass().getDeclaredMethods();
}
public void RandomExercise() {
Random randGenerator = new Random();
int rnd = randGenerator.nextInt(mMethods.length);
mMethods[rnd].invoke(this);
}
这是特定培训课程的一个例子
public class MatheMagic extends TrainingClasses{
public MatheMagic() {
/*Something*/
}
public String[] SomeExercise() {
/*Some code */
}
public String[] SomeOtherExercise() {
/*Some code */
}
}
在主要活动的这一点上,我想这样做:
private Object[] mTrainingClasses;
private MatheMagic mMathMag;
/*eventually other training classes*/
mMathMag = new MatheMagic();
mTrainingClasses[0] = mMathMag;
Random randGenerator = new Random();
int rnd = randGenerator.nextInt(mTrainingClasses.length);
Object aTrain = mTrainingClasses[rnd];
/*Return exercise*/
String[] mRes = aTrain.RandomExercise();
这是代码的相关部分,现在仍然不完整......但是当我尝试存储动态调用方法的结果时,由于遇到类型不匹配错误,我无法继续。 项目结构可能不正确,我应该使用其他一些架构......但是,我还没有发现任何更好的想法。
感谢任何人都能提供帮助。
-----------------------------------------------
谢谢你们的回答。 以下是可能需要此操作的最终工作代码:
/** Common interface for all exercises */
public interface Exercise {
public String[] run();
}
/** Common interface for all training classes */
public abstract class TrainingClass {
private Random rand = new Random();
public ArrayList<Exercise> mExerciseTypes = new ArrayList<Exercise>();
/** Run a random exercise */
public String[] runRandomExercise() {
int i = rand.nextInt(mExerciseTypes.size());
return mExerciseTypes.get(i).run();
}
}
/*Specific training class*/
public class MatheMagic extends TrainingClass {
public MatheMagic() {
class SomeExercise implements Exercise {
public String[] run() {
String[] mRes = new String[2];
mRes[0] = "Question type 1";
mRes[1] = "Answer type 1";
return mRes;
}
}
class SomeOtherExercise implements Exercise {
public String[] run() {
String[] mRes = new String[2];
mRes[0] = "Question type 2";
mRes[1] = "Answer type 2";
return mRes;
}
}
SomeExercise mN = new SomeExercise();
SomeOtherExercise mS = new SomeOtherExercise();
mExerciseTypes.add(mN);
mExerciseTypes.add(mS);
}
}
答案 0 :(得分:2)
我认为你应该重新思考你的设计。在大多数情况下,通常应避免使用反射。您真正需要反射的唯一时间是动态加载和执行代码(例如,JUnit框架动态加载并在名称作为命令行参数传递的类中执行测试)。
不是在类中随机执行一个方法,而是建议创建一个具有公共接口的Exercise
个对象的集合,随机选择其中一个,然后运行它。这是我正在思考的一些骨架代码:
import java.util.ArrayList;
import java.util.Random;
/** Common interface for all training classes */
public abstract class TrainingClass {
private Random rand = new Random();
protected ArrayList<Exercise> exercises = new ArrayList<Exercise>();
/** Run a random exercise */
public String[] runRandomExercise() {
int i = rand.nextInt(exercises.size());
return exercises.get(i).run();
}
}
/** Common interface for all exercises */
public interface Exercise {
String[] run();
}
public class MatheMagic extends TrainingClass {
/** Constructor creates all the exercises */
public MatheMagic() {
// Some exercise
exercises.add(new Exercise {
public String[] run() {
// Code for some exercise ...
}
});
// Some other exercise
exercises.add(new Exercise {
public String[] run() {
// Code for some other exercise ...
}
});
// etc ...
}
}
由于所有练习都属于Exercise
类型且具有通用run()
方法,因此无需使用反射。声明有点冗长,因为你需要为每个练习创建一个 anonymous inner class ,但额外的冗长是值得的,以避免反思!
答案 1 :(得分:1)
如果您手动创建训练课程数组(即不通过反射),您可以更改包含课程的数组类型:
private TrainingClasses[] mTrainingClasses;
以及您随机选择的类的类型:
TrainingClasses aTrain = mTrainingClasses[rnd];
这应该允许您在RandomExercise
上调用aTrain
方法。