Способ сказать "Для всех подклассов в моем проекте, которые расширяют этот суперкласс"? - PullRequest
1 голос
/ 31 декабря 2010

Вот кое-что, что меня немного озадачило, но все равно заинтриговало. В моей игре для Android у меня есть различные уровни, которые расширяют уровень суперкласса. То, что я пытаюсь сделать, - это создать levelDirectory (на основе Singleton DP), который по сути является объектом, в котором есть объект HashMap, в котором хранятся все подклассы уровня. Вот мой вопрос:

Мы все знакомы с расширенным циклом for, но как мне написать что-то, что будет эквивалентно

for(Level l : An Array Of Every Level Subclass In My Project that is an Extension of the Level Superclass){

HashMap.put(l.name, l);

}

Я пытаюсь построить систему, которая может динамически обновляться, когда я добавляю все больше и больше подклассов уровня. Я знаю, что в Level есть метод, который отправлял себя в статический каталог и вызывался в конструкторе Level. *

Большое спасибо

Ответы [ 6 ]

2 голосов
/ 31 декабря 2010

Вариант 1:

В последнее время мне пришлось решать аналогичную проблему в рамках JavaSE. Для этого я использую библиотеку Google Reflections:

http://code.google.com/p/reflections/

Однако я не уверен, что он может работать с Android. Я думаю, что стоит попробовать, так как он довольно прост в использовании. В вашем случае вы бы сделали что-то вроде:

Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends Level>> subTypes = reflections.getSubTypesOf(Level.class);

Это даст вам набор (подтипы) для итерации и поместит его в HashMap.

Вариант 2 :

Возможно, вы можете использовать пользовательские аннотации для аннотирования ваших классов уровня, например:

@Level public class MyCustomLevel {}

Затем используйте пользовательский процессор аннотаций, который реализует AbstractProcessor для обработки аннотации во время компиляции. Реализуйте метод process, чтобы найти все классы, аннотированные вашей аннотацией @Level. Теперь вы можете записать полные имена найденных классов в файл свойств в вашем META-INF каталоге. Из вашего приложения вы можете прочитать этот файл свойств и создать классы, используя отражение.

2 голосов
/ 31 декабря 2010
  1. Сам вопрос неверный.Вы не можете перебрать список («Подкласс каждого уровня в моем проекте») и получить экземпляры уровня.Я должен быть класса.

  2. Из контекста, я думаю, вы имели в виду "каждый экземпляр каждого подкласса уровня".Нет, это невозможно - виртуальная машина не является и не должна быть базой данных.Вы не можете просто запрашивать объекты, вы должны управлять ссылками в своем коде (но вы уже знали об этом - ваше конструкторское решение будет работать).

1 голос
/ 31 декабря 2010

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

0 голосов
/ 31 декабря 2010

Я думаю, что стандартным способом в «духе» Java является шаблон поставщика услуг.

Добавьте файл декларации в META-INF / services файла jar «plugin» и используйте java.util.ServiceLoader (http://developer.android.com/reference/java/util/ServiceLoader.html) для перечисления ваших провайдеров.

0 голосов
/ 31 декабря 2010

Я думаю, что вы можете сделать уровень интерфейсом, а затем проверить, является ли он интерфейсом.

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

interface Bicycle {

       void changeCadence(int newValue);   // wheel revolutions per minute

       void changeGear(int newValue);

       void speedUp(int increment);

       void applyBrakes(int decrement);
}

Для реализации этого интерфейса имя вашего класса изменится (например, на велосипед определенной марки, например, ACMEBicycle), и вы бы использовали ключевое слово Implements в объявлении класса:

class ACMEBicycle implements Bicycle {

   // remainder of this class implemented as before

}

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

0 голосов
/ 31 декабря 2010

Не знаю много об Android, но звучит так, как будто Reflection может помочь, так что вы знаете об отражении в Java?

EDIT

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

Моя идея состояла в том, чтобы проанализировать все каталоги проекта в поисках подклассов - это можно было сделать один раз в начале выполнения программы, но в нем были бы перечислены уровни, которые никогда не могут быть созданы ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...