views:

80

answers:

2

Suppose I have:

public class FightingZone<MobileSuitso, Background> {

    private MobileSuitCollection<MobileSuitso> msCollection;
    private BackgroundInfo<Background> bgInfo;

    public FightingZone(MobileSuitCollection<MobileSuitso> newCollection, BackgroundInfo<Background> newInfo) {
        this.msCollection = newCollection;
        this.bgInfo = newInfo;
    }

    ...

        ...// inside a method
        MobileSuitCollection temporaryCollection = new MobileSuitCollection<MobileSuitso>(); // /!\

}

The problem is MobileSuitCollection is an Interface, so I can't instantiate it. For example, I could do:

MobileSuitCollection temporaryCollection = new GundamMeisterCollection<MobileSuitso>();
MobileSuitCollection temporaryCollection = new InnovatorCollection<MobileSuitso>();
MobileSuitCollection temporaryCollection = new CannonFolderCollection<MobileSuitso>();

etc. However, to manipulate temporaryCollection, I need it to be of the same type as the one passed via parameter to my Class. So I thought about doing this:

if (msCollection instanceof GundamMeisterCollection) {
    ...
} else if (msCollection instanceof InnovatorCollection) {
    ...
} ...

I realize that is awful however. Is there a better way to do this? Would it be possible to keep a reference to the class used by the initial type and then instantiate the temporaryCollection with that?

+1  A: 

The code that you place in the if-clause can be placed in a Visitor :

// Generics skipped for brevity
interface MobileSuitCollectionVisitor {
   handleCollection(GundamMeisterCollection collection);
   handleCollection(InnovatorCollection collection);
   handleCollection(CannonFolderCollection collection)
}

class ConcreteVisitor implements MobileSuitCollectionVisitor { 
    // place all of the logic in the implemented methods
}

and then let MobileSuitCollection have a method:

void visit(MobileSuitCollectionVisitor visitor);

And in each implementation of MobileSuitCollection simply have

public void visit(MobileSuitCollectionVisitor visitor) {
    visitor.handleCollection(this);
}
Bozho
I was looking into using Reflection to get the class name and instantiate it from there. Supposing that's possible, wouldn't it make the code cleaner? Or is this still the preferred approach?
Setsuna F. Seiei
If you going to use Reflection, use class object instead of class name. Like that: `Class<Interface> cl=collection.getClass();Interface inst=cl.newInstance();`
Ha
Reflection should be last resort. The above approach is the object-oriented one.
Bozho
A: 

A quick and dirty way to do it would be to clone the original collection, then manipulate it as needed. A better way might be to add a newInstance() method to the interface, or pass in a factory to FightingZone.

Adam Crume