У меня есть 3 класса источников света (X, Y и Z), которые наследуются от более общего класса источника света.
2 из 3 классов имеют поле "позиция". (X и Y)
В другом методе я запускаю все источники света определенного списка, и я проверяю, является ли текущий источник света экземпляром Z. Если это не так, я хотел бы получить доступ к полю позиции X (или Y) без кастинга текущий экземпляр. Но компилятор мне не позволит, я хотел бы сказать, что во время выполнения было бы нормально получить доступ к этому полю.
Фактически в обоих случаях он не позволит мне получить доступ к полю без кастинга, хотя во время выполнения он не может сломаться.
Да, я мог бы написать пару других строк, чтобы справиться с этим, но я спрашиваю об этом из любопытства и потому, что мне нравится минималистичное кодирование.
for (Light light : lights) {
Vec vector;
if (light instanceof DirLight) vector = light.direction;
else vector = new Vec(intersectionPoint, light.position);
}
Часто необходимость броска - это признак плохого дизайна кода. В вашем случае я могу представить себе некоторые способы написания более чистого кода:
1. Каждая реализация Light может иметь метод, который возвращает вектор.
public abstract Vector getVector();
2. Если это не так, чтобы иметь такой метод, вы могли бы реализовать Visitor-Pattern следующим образом:
Легкий:
public abstract void visit(Visitor visitor);
Новый интерфейс:
public interface Visitor {
public void visit(Light1 light);
public void visit(Light2 light);
public void visit(Light3 light);
}
Применение:
light.visit(new Visitor() { ... });
Java строго типизирована. Вы пытаетесь получить доступ к члену, который существует в DirLight
но не на Light
, и это требует кастинга. Нет.
Это неправда, что вокруг этого нет. Вы можете использовать отражение, чтобы получить поле. Однако это, как правило, то, что должно использоваться только по очень сильным причинам, а не по причинам, подобным тем, которые вы задали в своем вопросе. Конечно, вам нужно просто выполнить бросок на объекте.
Но здесь вы можете получить любое поле объекта.
// initialize o
for (Field field : o.getClass().getDeclaredFields()) {
Object value = field.get(o);
if (value != null) {
System.out.println(field.getName() + "=" + value);
}
}