我有一个通用接口A<T>
,我有一个实现A<String>
的B类。我创建了一个扩展C
并实现B
的类A<Number>
。
对于C
,我收到一个编译错误:
A cannot be inherited with different type arguments <String> and <Number>.
为什么不允许这样做? 如果答案是类型擦除,请详细解释。
示例代码:
public interface A<T> {
}
public class B implements A<String> {
}
public class C extends B implements A<Number> {
}
答案 0 :(得分:3)
如果可以,老实说,这没有意义。
以下是该方案:
B
实施A
并将A<T>
绑定到A<String>
。C
继承自B
(已经绑定到A<String>
),您还试图实施A<Number>
您无法通过两种方式实施类型。
如果您希望以某种方式将Number
纳入C
,那么您必须在 C
上使用类型,而不仅仅是{ {1}}。
这会编译,但看起来很奇怪:
A
最终,这实际上归结为您的层次结构需要如何布局。如果您 真的 需要public class C<T> extends B implements A<String> {
}
和B
之间的关系,那么以这种方式具体化其类型是没有意义的;让他们使用C
作为通用。最后,凭借继承,您仍然可以访问T
中A
到B
的常规合同,因此您无需实施。
C
答案 1 :(得分:2)
§8.1.5中的Java语言规范声明如下:
类可能不会同时是两种接口类型的子类型 它们是同一通用接口的不同参数化 (§9.1.2),或通用接口参数化的子类型 和原始类型命名相同的通用接口,或编译时 发生错误。
此要求是为了支持而引入的 按类型擦除进行翻译(§4.6)。
这意味着在擦除之后,您的课程最终可能会使用相同签名的方法(如果有的话)。有关详细信息,请参阅Angelika Langer的site。