Java For循环和多态

时间:2011-12-26 21:38:53

标签: java for-loop iterator polymorphism

我想知道如何在不使用C#中的“instanceof”的情况下处理for循环中的多态性。 这就是我所拥有的:

抽象类A:

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);
    }
}

在setNodes()方法中这样的for循环是否可以在Java中使用?我的意思是,有没有办法让Java理解,在我的循环中,我想只迭代A对象列表中的所有C对象(这里可以是B或C对象)。

或许我不能以正确的方式或类似的方式使用多态...或者这可能是“instanceof”运算符用法的真实情况:)

(是的你是对的,我不喜欢“instanceof”操作符,它让我觉得我没有正确地做事情所以我需要用强制转换和instanceof修复它们。它看起来很“脏”我,但也许我错了,使用它很常见!)

谢谢!

3 个答案:

答案 0 :(得分:2)

有时您需要知道实例是哪个子类。我们无法确定您的案例是否属于其中之一。但是如果你需要实现这个,你应该考虑使用Visitor Pattern并且只实现你想要的子类的方法。这样就可以避免“脏”检查实例。

答案 1 :(得分:1)

Java中没有这种循环和过滤器。至于你是否正确使用多态,如果没有更多的上下文,很难说。如果B.childNodesC需要使用A上无法使用的方法,那么您可能只需使用instanceof来过滤C。但除此之外,更纯粹的OO方法是在A上定义一个方法来回答一些过滤问题,然后使B的地图具有A值。类似的东西:

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

B.setNodes将查看每个A是否有趣,并将其添加到其地图中。然后它会在每个doSomething()上调用A,并且多态将从那里获取它。

答案 2 :(得分:0)

这种结构在Java中是不可能的(至少通过Java 6)。该循环期望每个对象都是C的实例,并且不充当过滤器(并且它不应该)。一般来说,如果你正在循环你希望获得一切的东西。如果您想进一步过滤,那么这是一个单独的操作。使用instanceof来做这件事并没有什么可耻的(除了在检查对象的属性方面有羞耻感)。