Nano Hash - криптовалюты, майнинг, программирование

Как добавить объекты в массив, используя имя их класса, а затем вызывая любой из их методов?

Я пытаюсь добавить карты в список, используя имя их класса, а затем хочу вызвать один из их методов. Как я могу это сделать? У меня есть это на данный момент:

В карту суперкласса:

public static ArrayList<Object> CreateAllCards() throws ClassNotFoundException
    {
        ArrayList<Object> cardArray = new ArrayList<>();

        for (int n = 0; n<cardList.length; n++)
        {
            if (isCardAllowedToBeCreated[n])
            {
                Class card = Class.forName(cardList[n]);
                cardArray.add(card);
            }
        }

        return cardArray;
    }

    static String[] cardList = {
        "CrtAbyssalSpecter",
        "CrtAirElemental",
        "ArtAladdinsRing",
        "SorAmbitionsCost",
        "CrtAnabaShaman",
        "CrtAngelOfMercy",
        "CrtAngelicPage",
        //...
    };
}

Где-то еще, мой основной:

public static void main(String[] args) throws ClassNotFoundException {

    ArrayList<Object> cardList = Card.CreateAllCards();

    for (int n=0; n<cardList.size(); n++)
    {
        if (cardList.get(n) instanceof Creature)
        {
            // How to call a specific method?
        }
    }

}

Кроме того, есть ли способ напрямую создать массив карт с использованием каждого имени карты, а не создавать массив объектов (по каждому имени карты), как я?


  • Определяют ли классы ArtAladdinsRing конструктор по умолчанию? 20.07.2013
  • Да, это так (минимум 15 символов blablabla). 20.07.2013
  • Есть ли причина, по которой вы сохраняете имена классов в виде строк? Почему бы не использовать static class [], чтобы избежать метода CreateCards? Также как isCardAllowedToBeCreated[n] решает, какой класс создавать или нет? 20.07.2013

Ответы:


1

Вы заполняете список объектами, представляющими классы; вы не создаете из них объекты. Чтобы создать объекты, вызовите метод newInstance:

            Class card = Class.forName(cardList[n]);
            // Create object by calling the default no-arg constructor:
            cardArray.add(card.newInstance());

После этого вы можете вызывать определенные методы путем приведения, как уже было предложено в другом ответе:

    if (cardList.get(n) instanceof Creature)
    {
        Creature c = (Creature) cardList.get(n);
        c.creatureSpecificMethod();
    }

Однако может быть лучший, более гибкий, объектно-ориентированный подход. Разве у этих «карточных» объектов нет ничего общего? Если они это сделают, им, вероятно, следует реализовать тот же интерфейс или наследовать от одного и того же суперкласса, а проверки типа «если текущая карта является картой существа, сделайте X» можно было бы свести к минимуму. См. "Предпочтение полиморфизма InstanceOf и понижающему приведению".

Обновление:

Чтобы создать список Cards, вам нужны следующие изменения: Сначала объявите список как список Card:

ArrayList<Card> cardArray = new ArrayList<>();

Затем используйте метод asSubclass, чтобы "преобразовать" результат forName в подкласс Card:

Class<? extends Card> card = Class.forName(cardList[n]).asSubclass(Card.class);
cardArray.add(card.newInstance());
20.07.2013
  • Главное, что я должен создавать экземпляр каждого объекта по его имени объекта. Есть ли способ создать список карт «Карта» вместо «Объект» и по-прежнему создавать экземпляры каждой карты по имени их класса? 20.07.2013
  • У вас есть класс под названием Card? Являются ли CrtAbyssalSpecter, CrtAirElemental и т. д. подклассами Card? 20.07.2013
  • Да, я делаю (минимум 15 символов blablabla). 20.07.2013

  • 2

    Использование кастинга, например:

    public static void main(String[] args) throws ClassNotFoundException
    {
    
        ArrayList<Object> cardList = Card.CreateAllCards();
    
        for(Object card : cardList)
        {
            if(card instanceof Creature)
            {
                Creature creature = (Creature) card;
                creature.creatureMethod();
            }
        }
    }
    

    Кроме того, я изменил ваш стиль цикла for на более эффективный for each.

    20.07.2013
  • Разве цикл foreach не медленнее обычного цикла for? 20.07.2013
  • @SriHarshaChilakapati Не в этом случае, так как раньше он использовал .get(int element) каждый раз, что имеет эффективность O (n), тогда как foreach использует итератор, который равен O (1), см. этот ответ для получения дополнительной информации: stackoverflow.com/a/2113226/1276341 20.07.2013
  • Спасибо, что поделились этим ответом. Меня этому учили в моем классе GameDev, где нам нужно запросить список из почти 200 объектов в цикле while, который повторяется 30 раз в секунду. 20.07.2013
  • ArrayList.get(int) равно Θ(1) - поиск в массиве занимает постоянное время. 20.07.2013
  • Метод CreateAllCards возвращает массив классов, а не экземпляров. 20.07.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..