2017-06-29 12 views
0

でオブジェクト型を知らなくてもメソッドを適用します。は、私はJavaで2つのクラスを持っているのjava

public class Movie { 

     public String title; 

     public Movie(String t) { 
     this.title = t; 
     } 

     public String getAuthor(){ 
     return title; 
     } 

} 

私はこのようなリスト内のすべてのオブジェクトを置くしようとしている:

ArrayList myList = new ArrayList(); 

    Book book = new Book("William"); 
    Movie movie = new Movie("Titanic"); 


    myList.add(book); 
    myList.add(movie); 

その後、私はジョンが書いた本(または他の特定のタイトル)の数を数えたいと思います。 Javaはそれは私が句は、オブジェクト型ごとに時間をチェックした場合に使用することができるだろう

int counter = 0; 
    for (int i =0;i<myList.size();i++){ 
     if (myList.get(i).getAuthor().equals("John")){ 
      counter +=1; 
     } 

あるオブジェクトの種類を知らないので、私はGETAUTHOR()またはたgetTitle()メソッドを適用することはできません、異なるオブジェクトに異なるメソッドを適用することができますが、実用的なケースでは20以上のクラスがあり、コードを非常に長く保守しやすいので、これは実行可能ではありません。

誰かがこれに対する解決策を提案できますか?前もって感謝します!

+5

異なるリスト( 'Book'や' Movie'のような、 'Object'以外に共通のスーパータイプを持たないもの)を同じリストに入れるのは悪い習慣です。共通(抽象的な)スーパークラスまたはインタフェースを作成できます。 – Jesper

+2

また、ジェネリックスなしで 'ArrayList'のような生の型を使わないでください。 [未加工のタイプとは何ですか?なぜ使用しないのですか?](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-それ) – Jesper

+0

なぜ同じリストに全く異なるもの(書籍とムービー)を入れたいのですか?それらがあなたのために似ている場合は、それらを呼び出す必要があるメソッドを提供する同じインターフェイスを与える必要があります。もちろん反射を使うこともできますが、これは私がこの場合に示唆するものではありません。 –

答えて

6

作成:すべての書籍や映画を含むようにしたい場合は、

for (Object o : myList) {  
    if (o instanceof Book && ((Book)o).getAuthor().equals("John")){ 
     counter +=1; 
    } 
} 

をただしつのリストを、あなたは、より良い共通のインターフェースやスーパークラスを提供したいですインタフェース

public interface HasAuthor { 
    String getAuthor(); 
} 

両方のあなたのクラスで、このインタフェースを実装し、これを使用します。

+2

OPが 'Book'と' Movie'を所有していると仮定すると、これは良い解決策です。 – bradimus

0

まず、myList.get(i).getAuthor() == "John"は、文字列をequals()で比較する必要があるため、機能しません(理由についてはチュートリアルを参照してください)。

第2に、オブジェクトの型を知り、それに応じてメソッドを呼び出す必要があります(キャストなしでリフレクションを使用できますが、自宅で試してはいけません)。あなたのリストの繰り返し処理を行う場合、このようにあなたがチェックする必要があります。

//Make it abstract to not allow instances of this class directly 
abstract class PieceOfArt { 
    private String creator; 

    public String getCreator() { 
    return creator; 
    } 
} 

class Book extends PieceOfArt { 
    //Access the creator as the author 
    //note that I do this just for demonstration purposes, just using getCreator() would be perfectly fine 
    public String getAuthor() { 
    return getCreator(); 
    } 
} 

class Movie extends PieceOfArt { 
    //Access the creator as the director 
    //note that I do this just for demonstration purposes, just using getCreator() would be perfectly fine 
    public String getDirector() { 
    return getCreator(); 
    } 
} 

List<PieceOfArt> myList = ...; 
for(PieceOfArt p : myList) { 
    if(p.getCreator().equals("John") { 
    ... 
    } 
} 
+1

どこにでもifsをすることは、OPがやりたいことではありません。 – Markus

+0

OPは "私はif節を使用して、毎回オブジェクト型をチェックし、異なるオブジェクトに異なるメソッドを適用できますが、これは実行可能ではありません..."と述べています。この答えは、必要とされるものとは反対のものです。 – bradimus

2

あなたは2017年にArrayList myList = new ArrayList();を使用することはできません。世界は古くて誤りの多いプログラミングスタイルから移行しました。ジェネリックは2004年にJavaプログラミング言語に追加され、以来ジェネリック型引数なしでジェネリッククラスを使用しようとすると警告が出されます。これは次の問題に私を連れて来ます:

2017年に警告を無視することはできません。実際には警告を無視することはありませんでした。 ArrayList myList = new ArrayList();に注意を払うと、あなたのIDEは警告を出さなければなりません。

したがって、結論は、書籍と映画を同じコレクションに入れないことです。著者があるブッククラスと監督を持つムービークラスを持っている場合(私はタイトルを持つ映画の例を無視し、無意味なので "著者"として返します)、あなたはとMovieの両方で実装(オーバーライド)されているString getAuthor()メソッドを持つ、たとえばItemと呼ばれるインターフェイスまたは抽象基底クラス。

次に、あなたのmyListArrayList<Item>なり、ItemgetAuthor()メソッドを持っているので、あなたはmyList.get(0).getAuthor()を行うことができるでしょうし、それは本や映画であるかを知らなくても動作します。

0

BookMovieのように、共通のスーパークラス(java.lang.Object以外)を持たない、関係のない種類のオブジェクトを置くのは悪い習慣です。

これらのタイプに共通の抽象スーパークラスを定義し、そのタイプのListを作成できます。たとえば:

public abstract class Product { 
    private String title; 
    private String author; 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getAuthor() { 
     return author; 
    } 

    public void setAuthor(String author) { 
     this.author = author; 
    } 
} 

class Book extends Product { 
} 

class Movie extends Product { 
} 

List<Product>を作成し、それに動作します:

List<Product> products = new ArrayList<>(); 

Book book = new Book(); 
book.setTitle("Cooking"); 
book.setAuthor("Bob the Cook"); 
products.add(book); 

Movie movie = new Movie(); 
movie.setTitle("Romance at sea"); 
movie.setAuthor("John"); 
products.add(movie); 

int count = 0; 
for (Product product : products) { 
    if (product.getAuthor().equals("John")) { 
     count++; 
    } 
} 

注:getAuthor方法は、実際にMovieの場合はタイトルを返してはいけない、あなたのプログラムが本当に混乱になるだろう。

関連する問題