如果有人可以为我解决这个难题。我相信我错过了什么!
interface a { }
class b implements a { }
class c extends ArrayList<b> { }
class d {
d(ArrayList<a> param) {}
}
class e {
public static void main(String[] arg) {
d newd = new d(new c());
}
}
此代码有错误:
错误d(ArrayList<a>) is not applicable (actual argument c cannot be converted to ArrayList<a> by method invocation conversion)
当c
扩展ArrayList<a>
和c
实现ArrayList<b>
时,类b
肯定可以转换为a
!
我尝试过显式转换,但没有帮助。
将class c extends ArrayList<b>
改为extends ArrayList<a>
作为c
的集合b
和接口a
的目的是没有意义的仅用于显示目的。类d
也是一个通用的显示类,它依赖于接口a
中表达的功能,所以改变它也没有意义。
建议会很方便!
答案 0 :(得分:3)
这应该符合您的需求:
class d {
d(ArrayList<? extends a> param) {
}
}
c
不是ArrayList<a>
,而是ArrayList<? extends a>
,因为b
是a
的子类型。
答案 1 :(得分:0)
问题是ArrayList与ArrayList不同,即使b扩展A.如果D调用param.add(new AImpl()),其中AImpl是接口A的其他实现,会发生什么?
有关详细信息,请参阅The Java Generics Tutorial section on inheritance。
(顺便说一句,扩展一个ArrayList通常也不是一个好主意 - 大部分时间,你想要包装它,而不是扩展它。)
答案 2 :(得分:0)
应该是:
d(ArrayList<? extends a> param) {}
ArrayList不是ArrayList的子类,因为前者可以添加一个,而后者则不能。
答案 3 :(得分:0)
请尊重java命名约定:
interface A {
}
class B implements A {
}
class C extends ArrayList<B> {
}
class D {
D(ArrayList<A> param) {
}
}
class E {
public static void main(String[] arg) {
D newd = new D(new C());
}
}
因此,您的假设是ArrayList<B>
可以投放到ArrayList<A>
B implements A
。这不是真的,这不是泛型如何工作。你根本无法转换泛型类型。
尝试做类似的事情:
final ArrayList<Object> myNewArrayList = new ArrayList<String>();
提炼问题。
您需要使用bounded type parameters来解决此问题。将您的D
课程更改为:
class D {
D(ArrayList<? extends A> param) {
}
}
现在你会说:我想要一个任何类型的集合,只要它是A
。