Java для цикла и полиморфизма - PullRequest
1 голос
/ 27 декабря 2011

Мне было интересно, как я могу обрабатывать полиморфизм в цикле for без использования instanceof, как в C #. Вот что у меня есть:

Абстрактный класс А:

public abstract class A
{
    public abstract Map<Long, ? extends A> getNodes();
    public abstract void setNodes(Map<Long, ? extends A> n);
}

B и C классы, которые расширяют A и реализуют абстрактные методы A:

public class B
{
    private Map<Long, C> childNodesC;

    @Override
    public Map<Long, ? extends A> getNodes()
    {
        return childNodesC;
    }

    @Override
    public void setNodes(Map<Long, ? extends A> n)
    {
        for(C child : n)
            childNodesC.put(child.getId(), child);
    }
}

Является ли цикл for подобным этому в методе setNodes (), возможно в Java? Я имею в виду, есть ли способ для Java понять, что в моем цикле я хочу перебирать только все объекты C в списке объектов A (которые здесь могут быть объектами B или C).

Или, может быть, я неправильно использую полиморфизм или что-то в этом роде ... или, может быть, это истинный случай использования оператора instanceof:)

(Да, вы правы, мне не нравится оператор "instanceof", это заставляет меня думать, что я не все сделал правильно, поэтому мне нужно исправить их с помощью приведений и instanceof. Это выглядит "грязно", чтобы меня, но, возможно, я ошибаюсь, и это очень распространено!)

Спасибо!

Ответы [ 3 ]

2 голосов
/ 27 декабря 2011

Иногда бывают случаи, когда вам нужно знать, к какому подклассу относится экземпляр.Мы не можем действительно определить, является ли ваше дело одним из таких.Но если вам нужно реализовать это, вы должны рассмотреть возможность использования Visitor Pattern и реализовать только метод вашего подкласса.Таким образом вы избежите «грязных» проверок instanceof.

1 голос
/ 27 декабря 2011

Такой цикл и фильтр недоступны в Java.Что касается того, правильно ли вы используете полиморфизм, трудно сказать без некоторого дополнительного контекста.Если B.childNodesC нужно использовать метод, который недоступен в A, то вам, вероятно, нужно просто использовать instanceof, чтобы отфильтровать C s.Но в противном случае более чисто ОО-подходом было бы определение метода на A, который отвечает на некоторые вопросы фильтрации, и затем карта B имеет значения A.Что-то вроде:

A.isSomethingInteresting() -> false
A.doSomething() { ... }
C.isSomethingInteresting() -> true
C.doSomething() overrides { ... }

B.setNodes увидит, является ли каждый A чем-то интересным, и добавит его на свою карту, только если это так.Затем он будет вызывать doSomething() для каждого из своих A s, и полиморфизм заберет его оттуда.

0 голосов
/ 27 декабря 2011

Такая конструкция невозможна в Java (по крайней мере, в Java 6).Этот цикл ожидает, что каждый объект будет экземпляром C и не действует как фильтр (и не должен).В общем, если вы зацикливаетесь на чем-то, вы хотите получить все.Если вы хотите дополнительно отфильтровать, это отдельное действие.Нет ничего постыдного в использовании instanceof для этого (больше, чем стыд в проверке свойства объекта).

...