В текущем классе необходимо программно определять имя другого класса (вида "ClassNumPath + i" ) и далее вызывать его методы.
Файлы классов ClassNumPath0.java (а так же ClassNumPath1.java .. ClassNumPath5.java) существуют и их методы вызываются без ошибок, если обращаться к ним в коде напрямую, например:
ClassNumPath0.initPositions();
или
ClassNumPath4.initPositions();
.. то никаких проблем нет - все работает как надо, отрисовка в onDraw производится и прочее... Но мне нужно определять имя класса ClassNumPathХ динамически и иметь возможность менять это имя имя класса по ходу действия.
Часть кода над которым я бьюсь:
public class ClassNumPath extends SurfaceView implements SurfaceHolder.Callback {
...
int currentNum = 5;
String currentClassName;
Class cClass;
...
@Override
protected void onDraw(Canvas canvas) {
if (needInitialazation) {
currentClassName = "com.mytestapp.testapp.ClassNumPath" + currentNum;
cClass = Class.forName(currentClassName);
cClass.initPositions(); // Ошибка: Cannot resolve method 'initPositions()'
ClassNumPath5.initPositions(); // А это работает правильно
Log.d("INF", "currentClassName = " + currentClassName);
Log.d("INF", "cClass = " + cClass);
// Эти логи выдают правильное имя класса com.mytestapp.testapp.ClassNumPath5
}
...
cClass.checkState(); // Ошибка: Cannot resolve method 'checkState()'
ClassNumPath5.checkState(); // А это работает правильно
...
}
Итак, вопрос:
Каким образом можно обращаться к методам класса, чье имя было задано динамически?
Или, пожалуйста, подскажите вариант как по-другому решить задачу. Не хочется выстраивать большую конструкцию с операторами типа Case с выбором нужного имени класса в зависимости от значения currentNum, так как классов ClassNumPathХ может быть более 100 штук.
Ответ
Благодарю @nofate за помощь!
Я использовал предложенное им Решение №2 с объявлением интерфейса.
Действительно, все методы в пронумерованных классах ClassNumPathX одинаковы и вовсе не обязаны быть статическими.
Единственное замечание, в строке:
IClassNumPath classNumPath = (IClassNumPath) clazz.newInstance();
Android Studio выдавал ошибку на IClassNumPath, поэтому я заменил его на название интерфейса ClassNumPath (без префикса I):
В итоге решение получилось такое:
В классе ClassNumPath объявил интерфейс NumPath с набором общих методов для всех нумерованных классов 'ClassNumPathX`
public class ClassNumPath extends SurfaceView implements SurfaceHolder.Callback {
...
public static NumPath cNumPath;
...
// дать имя ClassNumPath интерфейсу внутри класса ClassNumPath уже нельзя
public interface NumPath {
void initPositions();
void checkState();
}
...
@Override
protected void onDraw(Canvas canvas) {
if (needInitialazation) {
currentClassName = "com.mytestapp.testapp.ClassNumPath" + currentNum;
Class clazz = Class.forName(currentClassName);
NumPath cNumPath = (NumPath) clazz.newInstance();
cNumPath.initPositions();
}
...
// Поскольку cNumPath объявлен как public, то можно пользоваться им в любом месте
cNumPath.checkState();
...
}
}
В самих нумерованных классах ClassNumPathХ даже и не пришлось ничего особо менять. Только добавил implements ClassNumPath.NumPath и @Override к методам и убрал из них static
public class ClassNumPath4 implements ClassNumPath.NumPath {
...
@Override
public void initPositions() {
...
}
@Override
public void checkState() {
...
}
}
Комментариев нет:
Отправить комментарий