从通用接口扩展 [英] extends from generic interfaces
问题描述
最后一行出了什么问题?
What wrong in last row?
interface I1<T>{}
class Class1 implements I1{}
class Class2 extends Class1 implements I1{} //valid
class Class3 implements I1<Number>{}
class Class4 extends Class3 implements I1<Number>{} //valid
class Class5 implements I1<Number>{}
class Class6 extends Class5 implements I1<Integer>{} //not valid
class Class7 implements I1{}
class Class8 extends Class7 implements I1<Number>{} // not valid
class Class9 implements I1<Number>{}
class Class10 extends Class9 implements I1{} // not valid !!!
为什么我不能这样做?
我在书中看到了它,但没有对此事的解释-仅供参考.
I saw it in book, but there are not explanation of this thing - only for information.
PS
例外文字:
java: GenericsTest.I1 cannot be inherited with different arguments:
<java.lang.Integer> and <java.lang.Number>
推荐答案
了解这一点有两点:
- Java泛型通常是类型不变的.这意味着,例如
I1<Number>
和I1<Integer>
是不同的类型.在大多数情况下,尽管Integer扩展了Number,它们还是无关紧要的. - 如果接口被声明为在超类上实现,则可以声明该接口再次在子类上实现.这是多余的,但允许.
- Java generics are normally type-invariant. This means that, for example, an
I1<Number>
and anI1<Integer>
are distinct types. For most purposes, they are unrelated, despite that Integer extends Number. - If an interface is declared as being implemented on a superclass, it can be declared to be implemented again on a subclass. It's redundant but it's allowed.
现在,不允许执行两次接口,而接口的通用类型是不同的.
Now, what is not allowed is implementing an interface twice, where the generic type of the interface is different.
例如,这是不允许的:
class NotAllowed implements I1<String>, I1<Integer> {}
I1
的类型在运行时被删除,因此您不能这样做.在运行时,I1<String>
和I1<Integer>
之间并没有真正的区别.他们两个都变成I1
.
The types of I1
are erased at run time so you cannot do that. At run time there is not really a difference between an I1<String>
and an I1<Integer>
. Both of them become just I1
.
由于与上述NotAllowed
不允许的原因相同,因此不允许使用带有Class5
和Class6
的示例.它两次实现相同的接口,但具有不同的泛型类型.
Your example with Class5
and Class6
is not allowed for the same reason as the above NotAllowed
is not allowed. It implements the same interface twice but with different generic types.
如果允许,这将是自相矛盾的,因为例如给出以下内容:
If it were allowed, it would be paradoxical, because for example given the following:
interface Face<T> {
public void method(T t);
}
如果我随后用不同的类型实现两次,这意味着必须有两个method
的通用类型的实现:
If I then implement this twice with different types, it would imply there must be two generically-typed implementations of method
:
class Implementation
implements Face<String>, Face<Integer> {
@Override
public void method(String s) {}
@Override
public void method(Integer i) {}
}
这是自相矛盾的,因为擦除操作还指示method
的两个实现在运行时都将变得相同.您不能在同一类中声明带有相同签名的方法,因此是不允许的.
This is paradoxical because erasure also dictates that both implementations of method
will become identical at run time. You cannot have methods with identical signatures declared in the same class so it's not allowed.
这篇关于从通用接口扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!