如果我有一个A类,其中包含A类儿童的列表,如
public Class A
{
protected List<A> children = new ArrayList<A>();
...
}
那么在子类B中是否可以拥有另一个C类的子级并在A类中创建对子列表的引用? A类具有其他类想要使用的方法,例如送孩子去。但是,A类是一般类,B和C更具体。因此,为了使代码的读取更容易并避免大量的类型转换,我希望超类的List能够引用子类的List。
因此,当我更新 otherChildren 时,子级列表也会更新。我想在下面的示例中做一些事情,但是这样做不起作用,也不能用(children =(List&lt; A&gt;)otherChildren)进行投放。
但是无论如何要实现这个目标吗?我真的很想避免所有的类型转换。
public Class B extends A
{
private List<C> otherChildren = new ArrayList<C>();
public B()
{
children = otherChildren;
...
// Modification of otherChildren will result in the same
// modification in children
}
}
public Class C extends A
{
...
}
答案 0 :(得分:3)
你不能这样做,因为他们是不同的类型。您可以对List<A>
的实例执行的操作之一是添加A
的任意实例;你不能在List<C>
上这样做,因为它是一种更受限制的类型。
修复方法是使A
采用类型参数:
public class A <T extends A> {
protected List<T> children = new ArrayList<T>();
// ...
}
public class B extends A<C> {
private List<C> otherChildren = new ArrayList<C>();
public B() {
children = otherChildren;
}
// ...
}
public class C extends A<? extends A> {
// Or some such
}
当然,此时你也可以说你完全不需要otherChildren
。您可以直接在子类中的children
上操作,它仍然可以在没有显式强制转换的情况下工作。
答案 1 :(得分:2)
通过让孩子们引用其他孩子,你试图给A一个List<C>
作为List<A>
的视图,然后A可以合理地期望将A对象添加到它认为是列表的内容中As,但实际上应该是Cs的集合。
这在概念上无效。
如果此作业有效,则可能在C中,您的otherChildren应声明为List<A>
。这引出了一个问题:为什么你不能直接使用children数组呢?
编辑:
我认为你需要一个更复杂的A,也许使用带有“extend”参数的泛型。所以A没有As的列表,但是没有As的列表。
答案 2 :(得分:2)
您所要做的就是将A类中的孩子声明更改为:
protected List<? extends A> children = new ArrayList<A>();