-1

How can I add a bunch of classes to an ArrayList<MyBaseClass> and then later retrieve a Class (derived from, but not MyBaseClass) from the ArrayList and use it to generate a new object of the actual Class retrieved (i.e. not MyBaseClass since that is abstract)

All classes that need to be added all derive from the same abstract base Class (MyBaseClass)

I can't really think of another way to achieve what I want to do, so hopefully this is possible... ?

ycomp
  • 8,316
  • 19
  • 57
  • 95

2 Answers2

7

To prevent the use of reflection, you are probably looking for the Abstract Factory Pattern. Here is a simple example how to implement it using Java 8:

private void run() {
    List<Supplier<MyBaseClass>> factories = Arrays
            .asList(Impl1::new, Impl2::new, Impl3::new);
    List<MyBaseClass> baseClassInstances = factories.stream()
            .map(Supplier::get)
            .collect(Collectors.toList());
}

public abstract class MyBaseClass {
}

public class Impl1 extends MyBaseClass {
}

public class Impl2 extends MyBaseClass {
}

public class Impl3 extends MyBaseClass {
}

See also How should I select which concrete implementation should be instantiated based on the user choice?

Community
  • 1
  • 1
Stefan Dollase
  • 4,530
  • 3
  • 27
  • 51
  • Of course, it only makes sense if `factories` is used more than once. Otherwise it’s an unnecessary complication of `List baseClassInstances = Arrays.asList(new Impl1(), new Impl2(), new Impl3());` – Holger Sep 15 '15 at 10:02
  • You are right, but that is exactly what the OP was looking for. – Stefan Dollase Sep 15 '15 at 14:48
3

Here is what I think you're asking for:

// get a list from somewhere
List<MyBaseClass> list = new ArrayList<MyBaseClass>();

// call list.add(...) a few times

// iterate over all the objects and check their sub class with "instanceof"
for (MyBaseClass item : list) {
    if (item instanceof MySubClass) {
        MySubClass subItem = (MySubClass) item;
        item.doThing();
    } else if (item instanceof OtherSubClass) {
        OtherSubClass subItem = (OtherSubClass) item;
        item.doThing();
    }
}

But if you find yourself needing to check if an object is the instance of a particular class, you're probably doing something wrong. Try creating an abstract method in MyBaseClass that can be implemented by each sub class in its own special way. Then, you can simplify the for loop to just this:

for (MyBaseClass item : list) {
    item.doThing();
}
Ben M.
  • 2,370
  • 1
  • 15
  • 23