Java泛型學習筆記 - (六)泛型的繼承


在學習繼承的時候, 我們已經知道可以將一個子類的對象賦值給其父類的對象, 也就是父類引用指向子類對象, 如:

1 Object obj = new Integer(10);

這其實就是面向對象編程中的is-a關系. 既然上面的代碼正確, 那么在泛型中, 也可以使用如下代碼:

 1 public class Box<T> {
 2     private T obj;
 3     
 4     public Box() {}
 5 
 6     public T getObj() {
 7         return obj;
 8     }
 9 
10     public void setObj(T obj) {
11         this.obj = obj;
12     }
13 
14     public Box(T obj) {
15         super();
16         this.obj = obj;
17     }
18 }

調用:

1 Box<Number> b = new Box<>();
2 Integer i = 10;
3 Double d = 2.3;
4 b.setObj(i);
5 System.out.println(b.getObj());
6 b.setObj(d);
7 System.out.println(b.getObj());

這是正確的, 因為10, 2.3的類型都是Number的子類. 但是, 假設我們有如下方法:

1 public static void print(Box<Number> b) {
2     System.out.println(b.getObj());
3 }

然后我們調用:

1 Box<Number> b1 = new Box<>();
2 Integer i = 10;
3 b1.setObj(i);
4 print(b1);

以上的程序也是能夠正常運行的, 但是如果我們改用如下的方式來調用:

1 Box<Integer> b2 = new Box<>();
2 b2.setObj(10);
3 print(b2); // 編譯失敗

這就不會通過編譯. 因為, 無論Integer和Number的關系如何, Box<Integer>和Box<Number>是沒有關系的, 他們之間唯一的關系就是他們都是Object的子類. 如圖所示:

(如果想要讓他們也擁有繼承關系, 請參看我的下一篇博文《淺析泛型中通配符的使用》)

那么泛型類之間擁有繼承(或實現接口)關系是怎樣的呢? 我們以List和ArrayList為例:
通過查看API文檔, 我們可以發現ArrayList類是這樣的:

1 public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable

而List接口又是:

1 public interface List<E>extends Collection<E>

這時, 我們就可以說ArrayList<String>實現了List<String>接口繼承了Collection<String>接口, 相信這樣的例子我們已經見的不少了:

1 List<String> list = new ArrayList<String>();

我們也可以自己定義具有繼承關的泛型, 下面是一個繼承了List接口的泛型接口:

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

如果我們有如下的類實現該接口:

1 PayloadList<String,String>
2 PayloadList<String,Integer>
3 PayloadList<String,Exception>

那么他們之間的關系就如圖所示:

 

總結: 兩個類(甚至是同一個類)的泛型所具有繼承(或實現)關系並不能代表這兩個類之間的關系. 除非這兩個類是有着明確的繼承(或實現關系), 其泛型間的關系並不能對其造成影響.

 References:

https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM