兩個問題
問題一:FatherClass和ChildClass是父子類的關系,那List<FatherClass>和List<ChildClass>是否也是父子類的關系?
問題二:倘若不是父子類關系,那么通過什么方式可以達到向上轉型的效果?
有兩個類Fruit和Apple,Apple繼承自Fruit,所以Fruit使Apple的父類,關系如下圖所示
示例代碼
public class GenericMain { public static void method1(Fruit fruit) { System.out.println("lingyejun eat fruit"); } public static void method2(List<Fruit> fruitList) { System.out.println("lingyejun eat fruit list"); } public static void method3(Collection<Fruit> fruitList) { System.out.println("lingyejun eat fruit collection"); } public static void method4(List<? extends Fruit> fruitList) { System.out.println("lingyejun eat extends fruit list"); } public static void main(String[] args) { method1(new Fruit()); method1(new Apple()); List<Fruit> fruitList = new ArrayList<>(); fruitList.add(new Fruit()); method2(fruitList); List<Apple> appleList = new ArrayList<>(); appleList.add(new Apple()); method2(appleList);// Compile Error method3(fruitList);// 可以向Collection<Apple>中傳入List<Apple> Set<Fruit> fruitSet = new HashSet<>(); method3(fruitSet);// 也可以向Collection<Apple>中傳入Set<Apple> method4(fruitList); method4(appleList); } }
method1的方法參數是Fruit類型,想method1方法中傳遞Fruit類型的變量或者Apple類型的變量都是可以的,因為Apple繼承自Fruit,會進行向上類型轉換。
method2的方法參數時List<Fruit>,我們試圖傳遞List<Apple>類型的變量是會出現編譯報錯,因為List<Fruit>和List<Apple>並不存在所謂的父子關系,是兩種無關的類型,所以編譯會報錯。
集合類的繼承關系
對於泛化的集合類型他們的繼承關系,以Collection<E>為例,ArrayList<E>實現了List<E>, 同時 List<E> 擴展自 Collections<E>。故 ArrayList<E>是 List<E>的子類型,List<E>是Collections<E> 的子類型。只要類型參數E一致,這三個類的繼承關系就得到保持。如下圖所示左右分別是Collection<Fruit>和Collection<Apple>的繼承鏈路。他們兩個是相互獨立的,沒有交叉的兩條關系鏈路,所以嘗試在method2中傳入appleList會編譯報錯。
同理,我們如果定義一個method3的參數列表為Collection<Fruit>,那么按照集合的繼承體系,方法參數中可以傳入泛型類型為Fruit的Collection下的所有子類型。
如果有這樣的需求List<Fruit>和List<Apple>想使用同樣的方法,那么我們該怎么樣定義參數列表呢?
可以使用extends關鍵字來限制泛型參數的適用范圍,List<T extends Fruit> 表示泛型實際參數可以是所有繼承自Fruit的類,如lApple等。
小結
泛型類和普通類一樣,可以擴展或實現其他的泛型類或接口。ArrayList<E>實現了List<E>接口,一個ArrayList<Apple>可以轉化為List<Apple>,而一個ArrayList<Apple>並不是一個List<Fruit>或者ArrayList<Fruit>。
如果我們要實現List<Fruit>和List<Apple>之間的關聯,可以使用泛型通配符在定義方法的時候指明這個List<? extends Fruit>來實現關聯。
本篇文章如有幫助到您,請給「翎野君」點個贊,感謝您的支持。