ObjectFactory с аргументом класса <?>

1

Я разрабатываю фабрику, которая может создавать объекты типа Ability с помощью параметра Class. Код для этой фабрики:

public static final class AbilityFactory {
    private AbilityFactory(){}

    public static <T extends Class<A>, A extends Ability> A getAbility(T clazz){
        A ability = null;
        try{
            ability = clazz.newInstance();
        } catch(InstantiationException | IllegalAccessException ex){
            ex.printStackTrace();
        }
        return ability;
    }
}

Код клиента выглядит примерно так:

Ability.AbilityFactory.getAbility(Firebolt.class));

Единственная проблема, которую я подумал об этом дизайне, заключается в том, что класс Ability является абстрактным, и вы можете передать что-то вроде этого:

Ability.AbilityFactory.getAbility(Ability.class)); 

что приводит к ошибке java.lang.InstantiationException.

Я хотел знать, могу ли я сделать некоторые ограничения, такие как "Расширяет способность, но не способность", или это просто плохой дизайн, и я должен передать, например, Enum в качестве аргумента в заводский метод для предотвращения этой ситуации.

  • 1
    Я не понимаю, почему это может быть проблемой, просто не передавайте Ability.class в качестве параметра.
  • 1
    Если все ваши подклассы Ability имеют конструктор по умолчанию, и вам нужен объект Class чтобы создать его экземпляр с помощью этой фабрики, тогда какой смысл? Почему бы просто не использовать новый оператор и избегать рефлексии?
Показать ещё 4 комментария
Теги:
class
generics

1 ответ

2
Лучший ответ

Единственное, что вы могли бы сделать, это предоставить интерфейс маркера, допустим, ConcreteAbility и <T extends Ability & ConcreteAbility>. Затем вам нужно реализовать ConcreteAbility со всеми конкретными возможностями.

  • 0
    Кажется, это хороший совет, но теперь я не могу передать аргумент в конструкторе моего чемпиона. До того, как он стал публичным Чемпионом (Class <? Extends Ability <C >> firstAbility) {...} и после того, как я изменил свою фабрику, следуя вашему совету: public static <T расширяет Class <A>, A расширяет Ability & ConcreteAbility> A getAbility (T clazz) {...} Мне нужно в моем конструкторе что-то вроде Class <? расширяет Ability <C> и ConcreteAbility> , но это не вариант из-за неправильного синтаксиса. Можете ли вы посоветовать мне обходной путь?
  • 1
    Ну, это действительно помогло мне. Я забыл, что мы можем использовать параметры именованного типа в конструкторах тоже. Спасибо!) Теперь код для моего конструктора: public <T расширяет класс <A>, A расширяет Ability & ConcreteAbility> Champion (T firstAbility, T secondAbility) {...}
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню