java中对随机选择的对象调用公共方法的更好方法

java中对随机选择的对象调用公共方法的更好方法,java,architecture,random,coding-style,arrayobject,Java,Architecture,Random,Coding Style,Arrayobject,祝大家好 我有一个带有runRandomExercise方法的抽象类,还有几个类扩展它以添加不同类型的练习 我现在想选择一个随机类型的练习,所以我需要随机选择一个类,并调用RunRandomExecute 现在我正在手动编写代码,我认为这不是最好的解决方案。但是,我不能只在数组中存储类,因为类类型不同,如果使用object[],我就不能调用runRandomExercise方法。有什么聪明的方法来处理这个问题吗 这是我到现在为止的密码。它是有效的,但添加其他类会很痛苦 /*Specific cl

祝大家好

我有一个带有runRandomExercise方法的抽象类,还有几个类扩展它以添加不同类型的练习

我现在想选择一个随机类型的练习,所以我需要随机选择一个类,并调用RunRandomExecute

现在我正在手动编写代码,我认为这不是最好的解决方案。但是,我不能只在数组中存储类,因为类类型不同,如果使用object[],我就不能调用runRandomExercise方法。有什么聪明的方法来处理这个问题吗

这是我到现在为止的密码。它是有效的,但添加其他类会很痛苦

/*Specific classes that extend abstract class TrainingClass with the runRandomExercise() method*/
private MatheMagic mMathMag;
private Mnemonics mMnemonics;
private String[] mTrainingClasses;


/*Initialize classes*/
mMathMag = new MatheMagic();
mMnemonics = new Mnemonics();

/*Manually store classe names*/
mTrainingClasses = new String[2];
mTrainingClasses[0] = "mMathMag";
mTrainingClasses[1] = "mMnemonics"; 


/*Return random exercise*/
public String[] RandomExercise() {
    Random aGenerator = new Random();

    /*Get random class name*/
    int rnd = aGenerator.nextInt(mTrainingClasses.length);
    String aChosen = mTrainingClasses[rnd];

    String[] aRes = new String[2];


    if (aChosen == "mMathMag") {
        aRes = mMathMag.runRandomExercise();
    } else if (aChosen == "mMnemonics") {
        aRes = mMnemonics.runRandomExercise();
    }

    return aRes;
}
编辑 以下是TrainingClass的定义:

/** Common interface for all exercises */ 
public interface Exercise { 
   public String[] run();
}

/** Common interface for all training classes */
 public abstract class TrainingClass {

  private Random mRandGen = new Random();
  public ArrayList<Exercise> mExerciseTypes = new ArrayList<Exercise>();

  /** Run a random exercise */
 public String[] runRandomExercise() {
    int i = mRandGen.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);
 } 

}

简单的解决方案是使用公共方法创建一个接口,并让所有类对其进行扩展

创建该类型的集合或数组,而不是对象;您可以简单地迭代或随机选择并调用所需的方法

对我来说,这就像是一种命令模式

public interface Exercise {
    void execute();
}
现在,您的类执行以下操作:

public class MatheMagic implements Execise {
    public void execute() {
        // special logic here.
    }
}
int numExercises = 1;
Exercise [] exercises = new Exercise[numExercises];
exercises[0] = new MatheMagic();
for (Exercise exercise : exercises) {
    exercise.execute();
}
然后你可以这样做:

public class MatheMagic implements Execise {
    public void execute() {
        // special logic here.
    }
}
int numExercises = 1;
Exercise [] exercises = new Exercise[numExercises];
exercises[0] = new MatheMagic();
for (Exercise exercise : exercises) {
    exercise.execute();
}

是的,是的,您可以将所有这些类存储在一个数组中,然后随机调用它们。怎样创建一个接口,并在所有类中从该接口派生。这样,您可以根据接口而不是实现来调用

duffymo比我快了几秒钟。如果我理解正确,它在抽象类上就不起作用了,对吗?因此,这意味着我需要在每个类中重写runRandomExercise方法,这将使我回到第一步。还是有一个我看不到的转变?我编辑了这个问题来说明培训课程是如何定义的。为什么不呢?只需创建需要子类重写抽象的类。我说的其他一切都是有效的。接口只是意味着更好的混合行为;它们也适用于您希望其中一个类扩展其他类的情况。我不知道我可以创建一个TrainingClass[]数组,然后用子类填充它。谢谢