1. 程式人生 > >Java引用型別轉換

Java引用型別轉換

java的引用型別轉換分為兩種:

  1. 向上型別轉換,是小型別到大型別的轉換
  2. 向下型別轉換,是大型別到小型別的轉換

現存在一個Animal動物類,貓子類和狗子類繼承於Animal父類;

複製程式碼
 1 public class Animal {
 2     private String name;
 3 
 4     public String getName() {
 5         return name;
 6     }
 7 
 8     public void setName(String name) {
 9         this.name = name;
10     }
11     
12     public void eat() {
13         
14     }
15 }
16 
17 public class Cat extends Animal {
18     public void eatFish() {
19         System.out.println("貓吃魚");
20     }
21 }
22 
23 public class Dog extends Animal {
24     public void eatBone() {
25         System.out.println("狗吃骨頭");
26     }
27 }
複製程式碼

  例項化一個cat物件,如下:

複製程式碼
 1 Cat cat1 = new Cat();   //使用子類引用例項化子類物件
 2 
 3 Animal cat2 = cat1; 
 4 //此時為向上引用轉換,小型別轉換為大型別,並沒有風險
 5 
 6 //Cat cat3 = cat2;   //報錯
 7 //由於cat2已經是Animal類的引用,所以此時為向下引用轉換,即大型別轉換為小型別,有資料溢位的風險
 8 //雖然有風險,但也可以強制轉換
 9 Cat cat3 = (Cat)cat2;  //強制轉換成功
10 
11 //Dog dog1 = cat2;         //因為子類不同所以不能這樣引用
12 //Dog dog1 = (Dog)cat2; //即使強制轉換也不行
複製程式碼

  雖然向下引用轉換會存在風險,但是可以利用java的instanceof關鍵字去解決這個問題。instanceof運算子用法:判斷是一個例項物件是否屬於一個類,是返回true,否則返回false。這樣我們可以優化上面的程式碼避免強制轉換型別時出現的問題:

複製程式碼
 1 /**  
 2 * instanceof運算子用法  
 3 * 運算子是雙目運算子,左面的操作元是一個物件,右面是一個類.當  
 4 * 左面的物件是右面的類建立的物件時,該運算子運算的結果是true,否則是false  
 5 *   
 6 * 說明:(1)一個類的例項包括本身的例項,以及所有直接或間接子類的例項  
 7 * (2)instanceof左邊操作元顯式宣告的型別與右邊操作元必須是同種類或右邊是左邊父類的繼承關係,  
 8 * (3)不同的繼承關係下,編譯出錯  
 9 */         
10 if(cat2 instanceof Dog) {
11     Dog dog = (Dog)cat2;
12 }else {
13     System.out.println("並不能轉換");
14 }
複製程式碼

  但是當子類例項物件統一放進父類引用物件陣列時,若要使用子類中的方法,必須先向下轉換型別為子類引用,不然編譯器會報錯

複製程式碼
 1 Animal[] animals = {
 2     new Cat(),
 3     new Dog()
 4 };
 5 
 6 
 7 //animals[1].eatFish();   //報錯
 8 if(animals[1] instanceof Cat) {
 9     Cat cat = (Cat)animals[1];
10 }