Как сделать ArrayList классов?

Как добавить кучу классов в ArrayList<MyBaseClass>, а затем получить из ArrayList класс (производный от, но не MyBaseClass) и использовать его для создания нового объекта фактического класса, полученного (т.е. не MyBaseClass, так как это абстрактно)

Все классы, которые должны быть добавлены, проистекают из одного абстрактного базового класса (MyBaseClass)

Я не могу думать о другом способе достижения того, что я хочу сделать, поэтому, надеюсь, это возможно...?

Ответ 1

Чтобы предотвратить использование отражения, вы, вероятно, ищете Аннотация Factory Шаблон. Вот простой пример, как реализовать его с помощью 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 {
}

См. также Как выбрать, какая конкретная реализация должна быть создана на основе выбора пользователя?

Ответ 2

Вот что я думаю, что вы просите:

// 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();
    }
}

Но если вам нужно проверить, является ли объект экземпляром определенного класса, вы, вероятно, делаете что-то неправильно. Попробуйте создать абстрактный метод в MyBaseClass, который может быть реализован каждым подклассом по-своему. Затем вы можете упростить цикл for только для этого:

for (MyBaseClass item : list) {
    item.doThing();
}