2016-05-28 13 views
0

注:私の質問にはどのように質問すればいいのか分かりません。ArrayList <SubClass>をArrayListとして渡す方法<BaseClass>

私はRSSパーサを書き始めています。ユーザーが情報を必要とするタグを指定できるようにし、parseInnerXmlByTagメソッドがそのタイプのArrayListを返すようにします。問題は、異なるタグには異なるプロパティがあることです。つまり、それぞれのタイプのタグ( "item"、 "channel"、 "entry" ...)のクラスを作成する必要があります。そこで私は空のRSSElementクラスを作成することにしました。次に、それを拡張するRSSItemクラスを作成しました。そこで、私のparseInnerXmlByTagはArrayList < RSSElements>を返します。 私の目標は、ユーザーが情報を必要とするタグを指定して1つのメソッドだけを呼び出すことです。 "item"を指定すると、メソッドはArrayList < RSSItem>を返します。

しかし、これらの二つのタイプがtechically関係を持っていないので、このような行は動作しません。

ArrayList<RSSElement> data = (method returning ArrayList<RSSItem>) 

私はトラブルの誰か場合ので、私は思っていたワイルドカードとサブタイプのまわりで私の頭をラップを抱えています私がこれまでに持っているものをチェックして、あなたの考えを私に与えてくれました。ここに私のコードはあります

public class RSSParser { 
public static ArrayList<RSSElement> parseInnerXmlByTag(String in, String tag) 
     throws XmlPullParserException, IOException{ 
    ArrayList<RSSElement> data = new ArrayList<>(); 
    StringReader input = new StringReader(in); 
    try{ 
     XmlPullParser parser = Xml.newPullParser(); 
     parser.setInput(input); 
     parser.nextTag(); 
     data = readFeed(parser, tag); 
    } 
    finally { 
     input.close(); 
     return data; 
    } 
} 

/* 
Returns an ArrayList of parsed RSSElements specified by "tag" 
*/ 
private static ArrayList<RSSElement> readFeed(XmlPullParser parser, String tag) 
     throws XmlPullParserException, IOException{ 
    ArrayList<RSSElement> data = new ArrayList<>(); 
    int event = parser.getEventType(); 

    //Parse until input is consumed 
    while(event != XmlPullParser.END_DOCUMENT){ 
     switch (event){ 
      case XmlPullParser.START_TAG: 
       if(parser.getName().equalsIgnoreCase(tag)){ 
        RSSItem item = RSSItem.processItem(parser); 
        data.add(RSSItem.processItem(parser)); 
       } 
       break; 
     } 
     event = parser.next(); 
    } 
    return data; 
} 

public static abstract class RSSElement{ 
    //Private constructor prevents instantiation 
    private RSSElement(){} 
} 

public static class RSSItem extends RSSElement{ 
    String title = ""; 
    String description = ""; 
    public RSSItem(String t, String d){ 
     title = t; 
     description = d; 
    } 

    @Override 
    public String toString() {...} 

    /* 
    Parses an RSS item tag into a container RSSItem (ONLY GRABS TITLE RIGHT NOW) 
    */ 
    protected static RSSItem processItem(XmlPullParser parser) 
      throws XmlPullParserException, IOException{ 
     String currentTag = ""; 
     String title = ""; 
     /* 
      while end tag hasn't been reached yet: 
      reaching the end tag means parser.getEventType == END_TAG && parser.getName = tag 
     */ 
     while(!(parser.next() == XmlPullParser.END_TAG && parser.getName().equalsIgnoreCase("item"))){ 
      Log.i("rssparser", "process entry"); 
      if(parser.getEventType() == XmlPullParser.START_TAG){ 
       currentTag = parser.getName(); 
      } 
      else if(parser.getEventType() == XmlPullParser.TEXT && currentTag.equalsIgnoreCase("title")){ 
       title = parser.getText(); 
       break; 
      } 
     } 
     return new RSSItem(title, description); 
    } 
} 
} 

このコードは完了し、ArrayListを返します。また、私はそれがRSSItemsを正確に私のログに基づいて解析していることを知っています。私はそれを使用する場所、それがは、それがRSSItemsのアレイを有する知らないので、明らかにそこにライン(私はここに投稿してる理由別名)

   @Override 
       public void onResponse(String response){ 
        ArrayList<? extends RSSParser.RSSElement> items = null; 
        try { 
         items = RSSParser.parseInnerXmlByTag(response, "entry"); 
        }... 

        if(items != null) { 
         for(int i = 0; i < items.size(); i++){ 
          //****DOESNT WORK**** 
          redditOutputTextView.append(items.get(i).title + "\n"); 
         } 
        } 
        else redditOutputTextView.setText("Items null"); 
       } 

が動作しないことができるしかし、ここではあります。だからうまくいけば、誰かが私がやろうとしていることを理解し、何か提案をすることができます。

答えて

2

あなたはあなたの次のコードを交換してくださいもらえますか?

+0

修正済み!まあそれと私が気付いた事実との組み合わせは、空のオブジェクトを作成していたかもしれない行でprocessItemメソッドを2回呼び出していました。ありがとう。 – sadelbrid

0

変更

ArrayList<? extends RSSParser.RSSElement> items = null; 

ArrayList<RSSParser.RSSElement> items = null; 

基本的に、あなたが今RSSElement

の任意のサブクラスのアイテムを取ることができ、リストを持っている古いものしか取ることができるリストでしたRSSElementから派生したいくつかのクラスの項目と、ワイルドカードを使用しているので、その型は何でもかまいませんので、コンパイラーはわかりません。 getと呼ぶことができますが、それは要素のスーパークラスを知っているからです:RSSElement

詳細については、this answerを参照してください。次の文で

//****DOESNT WORK**** 
redditOutputTextView.append(items.get(i).title + "\n"); 

//****WORKS**** 
Object obj=items.get(i); 
if(obj instanceof RSSItem){ 
    RSSItem rssItem = (RSSItem)obj; 
    redditOutputTextView.append(rssItem .title + "\n"); 
} 

をし、その結果を参照してください

+0

しかし、私のメソッドはArrayList を返し、アイテムに入れます。どのようにしてRSSItemプロパティにアクセスできますか? – sadelbrid

+0

最終的には、オブジェクトの型をチェックする必要があります。したがって、instanceofツリーを実行するか、抽象クラスのメソッドを作成してください。 –

0

あなたはこのように、リターン楽しいコードをUESすることができます

public static List<? extends Parent> test2(){ 
     List<Parent> parents = new ArrayList<Parent>(); 
     parents.add(new Son1()); 
     return parents; 
} 

をし、このようなリストを取得:

List<? extends Parent> parents = test2(); 

とOBV、CLSS SON1を()親を拡張します。

関連する問題