我想知道如何在不使用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修复它们。它看起来很“脏”我,但也许我错了,使用它很常见!)
谢谢!
答案 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
来做这件事并没有什么可耻的(除了在检查对象的属性方面有羞耻感)。