1

私は、トレーニング クラスを持つトレーニング プログラムに取り組んでおり、ランダム メソッド (エクササイズ タイプの 1 つ) を返す関数を使用しています。

このジェネリック クラスは、さまざまなタイプの演習を含むいくつかの特定のクラスによって拡張されます。

次に、特定のクラスの配列を作成し、ランダムなクラスを選択してから、ランダムな演習メソッドを呼び出します。

これがジェネリッククラスです

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();

これはコードの関連部分であり、まだ不完全です...ただし、動的に呼び出されたメソッドの結果を保存しようとすると、型の不一致エラーが発生するため、続行できません。プロジェクトの構造が間違っている可能性が高く、他のアーキテクチャを使用する必要があります...しかし、私はまだ良いアイデアを見つけていません。

助けてくれる人に感謝します。

–––––––––––––––––––––––––––––––––––––––––––</p >

答えてくれてありがとう。これが必要な人のための最終的な作業コードは次のとおりです。

/** 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);
 }

}
4

2 に答える 2

2

おそらくデザインを考え直すべきだと思います。ほとんどの場合、反射の使用は通常避けてください。リフレクションが本当に必要なのは、コードを動的にロードして実行する場合だけです(たとえば、JUnitフレームワークは、コマンドライン引数として名前が渡されるクラスでテストを動的にロードして実行します)。

Exerciseクラスでメソッドをランダムに実行する代わりに、共通のインターフェイスを使用してオブジェクトのコレクションを作成し、そのうちの1つをランダムに選択して、それを実行することをお勧めします。これが私が考えていることのスケルトンコードです:

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()方法があるため、リフレクションを使用する必要はありません。演習ごとに匿名の内部クラスを作成する必要があるため、宣言はもう少し冗長ですが、余分な冗長性は、反省を避けるために十分な価値があります。

于 2012-09-03T14:10:45.697 に答える
1

トレーニングクラスの配列を手動で作成している場合(つまり、リフレクションではない場合)、クラスを保持している配列タイプを次のように変更できます。

private TrainingClasses[] mTrainingClasses; 

ランダムに選択するクラスのタイプ:

TrainingClasses aTrain = mTrainingClasses[rnd];

RandomExerciseこれにより、でメソッドを呼び出すことができますaTrain

于 2012-09-03T13:58:30.507 に答える