views:

95

answers:

3

I want to have my models wrapped up in a ModelCollection which is mostly used for a ListView. The Collection has always the same attributes like title, totalResults (for Pagination) and it shall contain the listItem-Models in the ArrayList "items". However, these models have different types like "ModelCategory" or "ModelChain" and often have different Properties and Methods.

How can I achieve this in java with strong Typing discipline? I heart interface a the right way to do this. WHERE do I have to implement them?

public class ModelCollection {

              public ArrayList< ModelCategory OR ModelChain OR ModelXyz> items = new ArrayList<ModelCategory OR ModelChain OR ModelXyz>();

              private String id;
              private String title;
              private Long updated;

              private String linkSelf;
              private int totalResults;
              private int startIndex;

    /*
     more stuff like parsing a feed
    */

    }
A: 

Define a common interface for all your model classes which gives access to the properties they share.

public interface MooModel
  String getTitle();
  // etc

And define the List<MooModel>

willcodejavaforfood
Ok, and how does the code look in my view controller / activity? How can I access to special methods of the ModelCategory?
OneWorld
use "instanceof" keyword to check what concrete Model you have, and then cast your object to the specific Class.
deadsven
For dealing with special cases with each concrete Model I'd look into the Visitor pattern :)
willcodejavaforfood
+1  A: 

Make your ModelCategory, ModelChain, and ModelXyz implement an interface. Then have your collection be on that interface.

For instance:

public interface MyModel {
}

public class ModelCategory implements MyModel {
}

List<MyModel> list = new ArrayList<MyModel>();

To reference specific methods of each class, you will need to cast your list objects to the correct type.

List<MyModel> list = new ArrayList<MyModel>();
list.add(new ModelCategory());

ModelCategory model = (ModelCategory) list.elementAt(0);

Obviously, you can use whatever methods you need to iterate through your collections.

Tauren
+1  A: 

Solution of Tauren is correct, but remember to check instanceof like deadsven proposed, and the result is like:

    List<MyModel> list = new ArrayList<MyModel>();
    list.add(new ModelCategory());

    for(MyModel mymodelListElement: list) {
        //mymodelListElement.sameMyModelMethods()

        if(ModelCategory instanceof mymodelListElement) {
            ModelCategory modelCategoryElement = (ModelCategory)mymodelListElement;
        } else if(ModelChain  instanceof mymodelListElement) {
            ModelChain  modelChainElement = (ModelChain )mymodelListElement;
        } else if(ModelXyz instanceof mymodelListElement) {
            ModelXyz modelXyzElement = (ModelXyz)mymodelListElement;
        } else {
            //ignore
            //or
            //throw new RuntimeException("Wrong MyModel implementation")
        }

    }
Jan Wegner