Java™ 教程(泛型、繼承和子類型)

泛型、繼承和子類型

如你所知,只要類型兼容,就能夠將一種類型的對象分配給另外一種類型的對象,例如,你能夠將Integer分配給Object,由於ObjectInteger的超類型之一:編程

Object someObject = new Object();
Integer someInteger = new Integer(10);
someObject = someInteger;   // OK

在面向對象的術語中,這被稱爲「是一種」關係,因爲Integer是一種Object,所以容許賦值,可是Integer也是一種Number,因此下面的代碼也是有效的:segmentfault

public void someMethod(Number n) { /* ... */ }

someMethod(new Integer(10));   // OK
someMethod(new Double(10.1));   // OK

泛型也是如此,您能夠執行泛型類型調用,將Number做爲其類型參數傳遞,若是參數與Number兼容,則容許任何後續的add調用:學習

Box<Number> box = new Box<Number>();
box.add(new Integer(10));   // OK
box.add(new Double(10.1));  // OK

如今考慮如下方法:spa

public void boxTest(Box<Number> n) { /* ... */ }

它接受什麼類型的參數?經過查看其簽名,你能夠看到它接受一個類型爲Box<Number>的參數,可是,這是什麼意思?你是否能夠按照預期傳遞Box<Integer>Box<Double>?答案是「否」,由於Box<Integer>Box<Double>不是Box<Number>的子類型。3d

在使用泛型編程時,這是一個常見的誤解,但這是一個重要的學習概念。code

generics-subtypeRelationship.gif

給定兩個具體類型 AB(例如, NumberInteger), MyClass<A>MyClass<B>無關,不管 AB是否相關, MyClass<A>MyClass<B>的公共父級是 Object

有關如何在類型參數相關時在兩個泛型類之間建立相似子類型關係的信息,請參閱通配符和子類型。對象

泛型類和子類型

你能夠經過擴展或實現泛型類或接口來對其進行子類型化,一個類或接口的類型參數與另外一個類或接口的類型參數之間的關係由extendsimplements子句肯定。blog

使用Collections類做爲示例,ArrayList<E> implements List<E>List<E> extends Collection<E>,所以ArrayList<String>List<String>的子類型,也是Collection<String>的子類型,只要不改變類型參數,就會在類型之間保留子類型關係。繼承

generics-sampleHierarchy.gif

如今假設咱們想要定義咱們本身的列表接口PayloadList,它將泛型類型P的可選值與每一個元素相關聯,它的聲明可能以下:接口

interface PayloadList<E,P> extends List<E> {
  void setPayload(int index, P val);
  ...
}

PayloadList的如下參數化是List<String>的子類型:

  • PayloadList<String,String>
  • PayloadList<String,Integer>
  • PayloadList<String,Exception>

generics-payloadListHierarchy.gif


上一篇:有界類型參數

下一篇:類型推斷

相關文章
相關標籤/搜索