[英]How interface works with generics subtyping in java?
Consider the following classes.考虑以下类。
class Shape {}
class Circle extends Shape {}
class Rectangle extends Shape {}
class Node <T> {}
// In main method
Node<Circle> circleNode = new Node<>();
Node<Shape> shapeNode = circleNode; // ERROR
Following code will not compile because even though Circle is a subtype of Shape.以下代码不会编译,因为即使 Circle 是 Shape 的子类型。 Because of generics subtyping.
因为 generics 子类型。
But now consider the new Node class.但现在考虑新的节点 class。
class Node<T> implements Comparable<T> {
public int compareTo(T obj) { /* ... */ }
// ...
}
// In main method
Node<String> stringNode = new Node<>();
Comparable<String> comparable = stringNode;
Following code successfully compile.以下代码成功编译。 But there is no explanation on Java Docs.
但是 Java Docs 上没有解释。 How implementing an interface make it compile successfully.
实现接口如何使其编译成功。 And I didn't understand what happened exactly.
我不明白到底发生了什么。
You're comparing apples and oranges.你在比较苹果和橘子。
In your example, Node<Shape>
is to Node<Circle>
as List<Animal>
is to List<Dog>
.在您的示例中,
Node<Shape>
是Node<Circle>
,因为List<Animal>
是List<Dog>
。 However, Comparable<String>
is to Node<String>
as List<Animal>
is to ArrayList<Animal>
.但是,
Comparable<String>
是Node<String>
,因为List<Animal>
是ArrayList<Animal>
。
If you can have this parallelism clear in mind, all you need to remember is that a List<Dog>
is not a List<Animal>
and you have your answer.如果您可以清楚地记住这种并行性,那么您只需要记住
List<Dog>
不是List<Animal>
并且您有答案。
stringNode
is a Node<String>
, and that means assigning that variable to a Comparable<String>
-typed variable only requires the base type's relationship. stringNode
是一个Node<String>
,这意味着将该变量分配给Comparable<String>
类型的变量只需要基本类型的关系。 That's because the declaration Node<T> implements Comparable<T>
makes Node
a Comparable
subtype.这是因为声明
Node<T> implements Comparable<T>
使Node
成为Comparable
子类型。 With the type parameter being exactly the same, that makes Comparable<String>
assignable from Node<String>
(just as List<String>
is assignable from ArrayList<String>
)由于 type 参数完全相同,这使得
Comparable<String>
可以从Node<String>
> 赋值(就像List<String>
可以从ArrayList<String>
赋值一样)
In other words, the difference is not due to "implementing an interface make it compile successfully" ... it's due to the fact that Node<Shape>
is not assignable from Node<Circle>
(which you seem to understand), whether node is an interface or not.换句话说,差异不是由于“实现接口使其编译成功” ......这是由于
Node<Shape>
不能从Node<Circle>
分配(您似乎理解),无论节点是不是一个接口。
In 2nd example you're saying that for a given T
a Node<T>
is a Comparable<T>
.在第二个示例中,您说对于给定的
T
a Node<T>
是Comparable<T>
。 Thus, for T = String
you have Node<String>
is a Comparable<String>
.因此,对于
T = String
你有Node<String>
是一个Comparable<String>
。
However in 1st example you have 2 different types T
and U
where T
is a U
but there is nothing that says that Node<T>
is a Node<U>
.但是,在第一个示例中,您有 2 种不同的类型
T
和U
,其中T
是U
但没有任何内容表明Node<T>
是Node<U>
。
You might want to look for covariance and contravariance to learn more on this topic.您可能需要寻找协变和逆变来了解有关此主题的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.