2013-04-14 11 views
6

のメソッドにアクセスする方法をこんにちは私の問題に簡単な解決策がある場合、私は、のArrayList - サブクラス

を思ったんだけど、私はArrayListを持っている:

ArrayList <Animal> animalList = new ArrayList<Animal>(); 

/* I add some objects from subclasses of Animal */ 

animalList.add(new Reptile()); 
animalList.add(new Bird()); 
animalList.add(new Amphibian()); 

これらはすべてmove()のメソッドを実装しています。は、move()が呼び出されたときに飛んでいます。 は、私は大丈夫です。この

public void feed(Integer animalIndex) { 
    Animal aAnimal = (Animal) this.animalList.get(animalIndex); 
    aAnimal.eat(); 
} 

を使用して一般的な方法とスーパークラスのプロパティにアクセスすることができます知っている - しかし、今私は、サブクラスBirdがありmove()メソッドにアクセスしたいと思います。 私はキャストしてこれを行うことができますAnimalBirdとして:私の状況で

Bird aBird = (Bird) this.animalList.get(animalIndex); 
aBird.move(); 

私はそれが意味するように私は、各サブタイプのために上記のコード1の3つの異なるセットを持って、これを行うにはしたくありませんAnimal

少し冗長であるようですが、より良い方法がありますか?あなたのケースでは

+3

はなぜ動物を使用すると、サブクラスでオーバーライドし '移動()'メソッドを持っているでしょうか? –

+0

...コールを移動しますか?サブクラスの実装が呼び出されていない場合は、わからないことがあります。 –

+1

@ user2278797ちょうどあなたが知っていることは、あなたの質問を編集してより良い書式設定をし、クラスの名前を変更したことです(コードに矛盾していた):追加した行の名前から 's'-esを削除しました'animalList'。彼らは次のとおりでした: 'animalList.add(新しい爬虫類());動物リストadd(新しい鳥()); animalList.add(新しい両生類()); 'そして、今は:' animalList.add(new Reptile()); animalList.add(new Bird()); animalList.add(新しい両生類()); '。あなたのコードでそれらを使用した場合は、それに応じて変更するか、質問のコードを再編集してください。 – acdcjunior

答えて

12

各サブクラスの動作が異なるため、実際にはスーパークラスからこれを行うのは良い方法ではありません。

moveメソッドを実際に呼び出すには、Animalをスーパークラスからインターフェイスに変更します。次にmoveメソッドを呼び出すと、目的のオブジェクトに対して適切な移動メソッドを呼び出していることを確認できます。

一般的なフィールドを維持する場合は、抽象クラスAnimalBaseを定義し、すべての動物にそれをビルドする必要がありますが、実装ごとにAnimalインターフェイスを実装する必要があります。

例:

public abstract class AnimalBase { 
    private String name; 
    private int age; 
    private boolean gender; 

    // getters and setters for the above are good to have here 
} 

public interface Animal { 
    public void move(); 
    public void eat(); 
    public void sleep(); 
} 

// The below won't compile because the contract for the interface changed. 
// You'll have to implement eat and sleep for each object. 

public class Reptiles extends AnimalBase implements Animal { 
    public void move() { 
     System.out.println("Slither!"); 
    } 
} 

public class Birds extends AnimalBase implements Animal { 
    public void move() { 
     System.out.println("Flap flap!"); 
    } 
} 

public class Amphibians extends AnimalBase implements Animal { 
    public void move() { 
     System.out.println("Some sort of moving sound..."); 
    } 
} 

// in some method, you'll be calling the below 

List<Animal> animalList = new ArrayList<>(); 

animalList.add(new Reptiles()); 
animalList.add(new Amphibians()); 
animalList.add(new Birds()); 

// call your method without fear of it being generic 

for(Animal a : animalList) { 
    a.move(); 
} 
+0

しかし、サブクラス間で共有されるすべての一般的なメソッドと動作についてはどうでしょうか。別々のサブクラスで同じことを行い、同じことを記述する同じメソッドとプロパティを宣言することは冗長ではないでしょうか?たとえば、私はいくつかの共通のプロパティ名、性別、色などを持っていて、食べ物や睡眠のようないくつかのメソッドを持っています。途中であなたの素早い返信をありがとう。 – whiteElephant

+0

その時点で、必要なフィールドを提供する 'AnimalBase'という抽象オブジェクトを持つことができます。これから拡張し、 'Animal'インターフェースを実装したいと考えています。 – Makoto

+0

ありがとうございました。この問題を解決する正しい方法があるかどうか尋ねることはできますか?例えば基本抽象クラスを使用し、他のメソッドを実装する方が良いでしょうか、または特定のメソッドを空白にして、各サブクラスに対してオーバーライドする方がよいでしょうか? Cheers – whiteElephant

0

、次は仕事ができるが、時間の複雑さはO(n)は次のとおりです。

public void moveBird(){ 
    for(Animal aminal:animalList){ 
     if(animal instanceof Bird){ 
      aninmal.move(); 
     } 
    } 
} 
+0

私は各動物がmove()メソッドを持っていると仮定します。 – BlackJoker

1

あなたは任意の鋳造を行う必要がありいけません。オブジェクトが鳥である場合にオーバーライドされたメソッドは、[シンプルな多型]上記のコード

Animal aAnimal== this.animalList.get(animalIndex); 
aAnimal.move(); 

呼び出される必要があり、鳥のメソッドを呼び出す必要があり、そうではありませんか?

キャスティングは解決策ではありません。キャストするオブジェクトはどのように決定しますか? instanceOfを使用する必要があります。

+0

ありがとう、可能な解決策かもしれない。私はあなたが何を意味するのか分かりません。そして、キャスティングは解決策ではありません。キャストするオブジェクトはどのように決定しますか?あなたはinstanceOf "を使用する必要があります"、ユーザーはオブジェクト、すなわち動物をクリックし、それはarrayListに配置されている場所のインデックス番号を渡すでしょう。乾杯 – whiteElephant

+0

あなたはこうしています:animalList.add(newオブジェクトを取得する際に、どのオブジェクトが適切なキャストを実行するかを追跡する必要があります。 – Lokesh

+0

私はそうだと思います - これを代わりにした場合 – whiteElephant

-1
Bird getMyBird(Integer aniInteger) { 
     Bird b = new Bird(); 
     //Do somthig with bird object... 

     return b; 
     //get your modifeid bird object 
    } 

    Bird myBird = animalList.get(animalIndex); 

    myBird.move(); 
+2

これでも何をやっているのですか?私がしたかったのは、どんな種類の動物でも「動かす」ということでした。なぜあなたはバードに焦点を当てているのですか? – Makoto

+0

はい、鳥に焦点が当てられていません - それを例として使用していました。 – whiteElephant