我目前正在关注以下页面上关于Java的Generics的示例: http://docs.oracle.com/javase/tutorial/java/generics/types.html
public interface Pair<K, V> {
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair<K, V> {
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);
我的问题是关于最后创建变量的行。一开始,从对接口开始,而另一个从OrderedPair类开始。使用哪一个是否有区别?我只是想了解为什么代码不同。
答案 0 :(得分:2)
代码无效。 Java不允许在同一范围内使用两个相同名称的变量。
如果名称为p1
和p2
,则每个名称都会引用类OrderedPair<String,Integer>
的不同对象。在第二种情况下,您可以省略new
中的泛型参数,因为它们已经使用变量类型(变量名前的OrderedPair<String, Integer>
)指定。在第一种情况下,对象的类型是变量类型的子类。这对每个多态都有效。通用参数被指定了两次,虽然多余也是有效的。
如上所述,p1
和p2
引用了OrderedPair<String,Integer>
类型的对象。但是,p1
和p2
具有不同的静态(已声明)类型。在这种情况下,这意味着:
OrderedPair
有一个方法reverseOrder
(只是说某事)不是从Pair
继承的,那么p1.reverseOrder()
将无效(即使引用的对象是正确的类型,但编译器不知道这一点),但p2.reverseOrder()
将是。在这里,p2
“比p1
更好”(因为您需要更多的特异性而p2
拥有它)。UnorderedPait implements Pair
,则可以将此类型的新实例分配给p1
,但不能分配给p2
。在这里,p1
“比p2
更好”(因为您需要更多的通用性,而p1
有更多的一般性。)答案 1 :(得分:0)
第一个使用Pair的引用。有了这个,您可以指向Pair接口的任何实现 - OrderedPair,SortedPair,LongPair等。
但是使用第二个引用,您只能指向OrderedPair的对象
答案 2 :(得分:0)
如果OrderedPair
类中的方法未在Pair
界面中列出,那么您需要一个类型为OrderedPair
的表达式才能给他们打电话。换句话说,您希望将变量声明为OrderedPair
,然后调用该变量上的方法。另一方面,如果您仅使用Pair
界面中列出的方法,则可以将变量声明为Pair
,并在其上调用方法。你可能想要做后者有两个原因。
Pair
的变量可以引用实现Pair
的其他类的对象 - 您可能有UnorderedPair
,PrettyPair
等等,它们不是{的子类{1}}。OrderedPair
方法 - 任何特定于Pair
的方法都不会被使用。