我们在使用数组,泛型集合的过程中不可避免的会碰到多态,或者说什么情况下能如何使用父数组引用子数组(集合、泛型)呢?
数组在多态中的使用
元素为父类型的数组引用可指向元素为子类型的数组对象
当数组被调用时由当前引用确定数组元素的类型
当元素为父类型的数组引用指向了元素为子类型的数组对象时,不可通过父类型的数组引用向集合加入除子类型及其下层级的之外的元素(可通过编译,运行过程出错)
1 /*验证: 2 *animals和dogs可以引用同一个数组 3 *当animals引用数组时,数组元素为Animal类型 4 *当dogs引用数组时,数组元素为Dog类型 5 */ 6 7 public class Animal{ 8 private void showClass(){ 9 System.out.println("数组元素为Animal类型"); 10 } 11 12 public static void main(String[] args){ 13 //animals和dogs可以引用同一个数组 14 Dog[] dogs = {new Dog(), new Dog()}; 15 Animal[] animals = dogs; 16 17 //当animals引用数组时,数组元素为Animal类型 18 animals[0].showClass(); 19 //当dogs引用数组时,数组元素为Dog类型 20 dogs[0].showClass(); 21 //不可通过父类型的数组引用向集合加入除子类型及其下层级的之外的元素(可通过编译,运行过程出错) 22 animals[0] = new Animal(); 23 } 24 25 } 26 27 class Dog extends Animal{ 28 public void showClass(){ 29 System.out.println("数组元素为Dog类型"); 30 } 31 }
泛型在多态中的使用
ArrayList<父类型>无法引用ArrayList<子类型>
1 /*验证: 2 *animals无法引用dogs数组 3 * 4 */ 5 import java.util.*; 6 7 public class Animal{ 8 9 public static void main(String[] args){ 10 //animals无法引用dogs数组 11 ArrayList<Dog> dogs = new ArrayList<Dog>(); 12 ArrayList<Animal> animals = dogs; /* 无法通过编译 */ 13 } 14 15 } 16 17 18 class Dog extends Animal{ 19 20 }
为了弥补泛型的缺陷,java引入了一种“万用字符”——ArrayList<? extends object>
此类型集合可引用任何参数上继承、实现了参数类型(包括参数类型本身)的集合
1 /*万用字符 2 *animals可以引用dogs集合 3 *当animals引用集合时,集合元素为Dog类型 4 *当dogs引用集合时,集合元素为Dog类型 5 *无法通过animals对集合进行修改 6 */ 7 import java.util.*; 8 9 public class Animal{ 10 public void showClass(){ 11 System.out.println("集合元素为Animal类型"); 12 } 13 14 public static void main(String[] args){ 15 //animals可以引用dogs数组 16 ArrayList<Dog> dogs = new ArrayList<Dog>(); 17 dogs.add(new Dog()); 18 ArrayList<? extends Animal> animals = dogs; 19 //当animals引用集合时,集合元素为Dog类型 20 animals.get(0).showClass(); 21 //当dogs引用集合时,集合元素为Dog类型 22 dogs.get(0).showClass(); 23 //无法通过animals对集合进行修改(无法通过编译) 24 //animals.add(new Dog()); 25 26 } 27 28 } 29 30 31 class Dog extends Animal{ 32 public void showClass(){ 33 System.out.println("集合元素为Dog类型"); 34 } 35 }
集合在多态中的使用
当然List<object>集合可引用ArrayList<object>集合