我目前面临基础和子类的问题。
虽然将单个对象作为参数(单个方法),但编译器不会抱怨。
但如果涉及到列表,编译器会强制我将列表声明为<? extends Base>
之后我不再允许将基类型的对象添加到该列表中。
如何在一个列表中使用这两种类型(Base和Subclass)?
public class Generics {
class Base { }
class Sub extends Base{ }
interface I {
public void list( List<Sub> list );
public void single( Sub p);
}
class C implements I {
public void list( List<Sub> list) { }
public void single( Sub p) { }
}
void test() {
C c = new C();
c.single( new Sub() );
c.list( new ArrayList<Base>() ); // The method list(List<Generics.Sub>) in the type Generics.C is not applicable for the arguments (ArrayList<Generics.Base>)
}
public static void main( String[] args) {
Generics g = new Generics();
g.test();
}
}
答案 0 :(得分:1)
只需将所有列表声明为
即可List<Base> list;
然后,您可以添加Base
个对象和任何子类的对象。
答案 1 :(得分:1)
变化:
public void list(List<Sub> list);
为:
public void list(List<? extends Base> list);
只使用List<Base>
会给你编译错误,如下所示:
public static void main(String[] args) {
List<Sub> subs = new ArrayList<Sub>();
doSomethingWith(subs); // The method doSomethingWith(List<Base>) in the type Main is not applicable for the arguments (List<Sub>)
}
private static void doSomethingWith(List<Base> bases) {
// Do something with bases
}
如果您要传递的只是List<Base>
到doSomethingWith
,那么这一点没有实际意义,因为这不会给您带来编译错误。如果您要传递特定类型的列表(例如上面的List<Sub>
),则需要将doSomethingWith
更改为:
private static void doSomethingWith(List<? extends Base> bases) {
这解决了这个问题。你也可以在调用者控制杆上做这件事(但有点麻烦):
List<Sub> subs = new ArrayList<Sub>();
doSomethingWith(new ArrayList<Base>(subs));
通配符(?
)方法的一个问题是您无法将新项添加到列表中。要做到这一点,你需要像:
private static <B extends Base> void doSomethingWith(List<B> bases) {
然后只将B
个实例添加到bases
。
答案 2 :(得分:1)
以下是两种方法....
public void inTake(List<? extends Base> list){
}
或强>
public T extends Base void inTake(List<T> list){
}