Скажите Java-компилятору, что во время выполнения поле будет доступно?

1

У меня есть 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);
}
Теги:
polymorphism
casting
inheritance
compiler-errors

3 ответа

2

Часто необходимость броска - это признак плохого дизайна кода. В вашем случае я могу представить себе некоторые способы написания более чистого кода:

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() { ... });
  • 0
    Я буду использовать первый совет. Сколько стоит кастинг во время выполнения?
  • 0
    Сколько стоит литье? Смотрите этот вопрос
1

Java строго типизирована. Вы пытаетесь получить доступ к члену, который существует в DirLight но не на Light, и это требует кастинга. Нет.

0

Это неправда, что вокруг этого нет. Вы можете использовать отражение, чтобы получить поле. Однако это, как правило, то, что должно использоваться только по очень сильным причинам, а не по причинам, подобным тем, которые вы задали в своем вопросе. Конечно, вам нужно просто выполнить бросок на объекте.

Но здесь вы можете получить любое поле объекта.

    // initialize o
    for (Field field : o.getClass().getDeclaredFields()) {
        Object value = field.get(o); 
        if (value != null) {
            System.out.println(field.getName() + "=" + value);
        }
    }

Ещё вопросы

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