4

スーパークラス「Animal」とサブクラス「Cat」、「Dog、Bird」があるとします。可能な各サブクラスのインスタンスをインスタンス化できるクラスインスタンスではなく、サブクラスタイプの配列を持つ方法はありますか?

簡単にするために、私はこれが欲しい:

Pseudo code: For each possible subclass of "Animal": create an instance of that class.

どうやってやるの?

編集:これらのサブクラスのインスタンスの配列は必要ありません。オブジェクト型の配列が必要です。

4

3 に答える 3

6

それを実現するために、Ploymorphism を使用できます。

Animal[] animalArray = new Animal[10];
animalArray[0] = new Dog();
animalArray[1] = new Cat();

基本的に動物クラスのすべてのサブクラス。オブジェクトを取得したい場合は、単に typecaset することができます

Dod dog = (Dog)animalArray[0];

クラスを知るには、 getClass() メソッドを簡単に使用できます。例えば

    Animal[] animalArray = new Animal[10];
    animalArray[0] = new Dog();
    System.out.println(animalArray[0].getClass());

印刷されますclass Dog

于 2013-07-19T03:57:53.940 に答える
2

OPのコメントの後、リフレクションを使用しても、
クラスのすべてのサブタイプを取得する方法はありません。
しかし、別の方法でそれを行うことができます。これが唯一の、しかし最も長い方法であると言えます。

  • クラスパスに存在するすべてのクラスの名前のリストを取得します
  • 各クラスをロードしてテストし、目的のクラスまたはインターフェースのサブクラスまたは実装者であるかどうかを確認します



OPのコメントの前に答える

あなたの質問はまだ明確ではありませんが、またはのインスタンスであっても、すべてのインスタンスを格納する配列またはコレクションを使用したいと思いsuperclassますsubclass
次に、このようにする必要があると思います。

List<Object> list = new ArrayList<Object>();
         list.add(new Cat());
         list.add(new Dog());
         list.add(new Animal());
         list.add(new Cat());

         for (int i = 0; i < list.size(); i++) {

             if(list.get(i) instanceof Cat){
                 System.out.println("Cat at "+i);
             }else if(list.get(i) instanceof Dog){
                 System.out.println("Dog at "+i);
             }else if(list.get(i) instanceof Animal){
                 System.out.println("Animal at "+i);
             }
        }

このコードはテストされています
注:サンプル コードの場合のように親クラス チェック (list.get(i) instanceof Animal)を一番上に配置しないでください。 if-else if-else if)(list.get(i) instanceof Animal)および(list.get(i) instanceof Cat)返されるオブジェクトが Cat オブジェクトである場合、オブジェクトを Animal として返します。

于 2013-07-19T03:32:21.567 に答える
1

別の回答で述べたように、これは純粋なリフレクションでは不可能です。

このケースを具体的に処理するためにクラスをカスタマイズできない場合は、クラスローダーからクラスを反復処理するか、後で要求されたときに情報を内部データ構造に追加するカスタムクラスローダーを使用する必要があります。すべてのクラスで繰り返す必要はありません。

クラスローダーコードに飛び込むことに興味がないと仮定すると (興味がないように思えます)、これを行うための次善の方法は、クラスの読み込み時に実行される静的コードをクラスに追加することです。例えば:

public class Animal {
    protected static List subclasses = new ArrayList();
    //...
}

public class Cat extends Animal {
    static { 
        subclasses.add(Cat.class);
    }
    //...
}

これは基本的にカスタム クラス ローダーで行うことであり、このコードはクラスではなくクラス ローダーに存在します。

すべてのサブクラスに対してこのパターンを繰り返します。次に、インスタンスを作成する場合は、subclassesリスト内にクラス参照があり、これを使用してインスタンス化しますClass.newInstance(または、コンストラクターに引数がある場合は別の適切なリフレクション メソッド)。

于 2013-12-11T00:47:58.957 に答える