Java基礎-物件型別轉換
阿新 • • 發佈:2021-09-29
型別轉換總結
示例
物件的型別轉換
1 class Animal { 2 public String name = "Animal:動物"; 3 public static String staticName = "Animal:可愛的動物"; 4 5 public void eat() { 6 System.out.println("Animal:吃飯"); 7 } 8 9 public static void staticEat() { 10 System.out.println("Animal:動物在吃飯");11 } 12 } 13 class Cat extends Animal { 14 public String name = "Cat:貓"; 15 public String str = "Cat:可愛的小貓"; 16 public static String staticName = "Dog:我是喵星人"; 17 18 @Override 19 public void eat() { 20 System.out.println("Cat:吃飯"); 21 } 22 23 public static voidstaticEat() { 24 System.out.println("Cat:貓在吃飯"); 25 } 26 27 public void eatMethod() { 28 System.out.println("Cat:貓喜歡吃魚"); 29 } 30 } 31 public class TransType { 32 public static void main(String[] args) { 33 Animal animal = new Cat(); 34 // 向下轉型 35 Cat cat = (Cat) animal;36 37 // 輸出Animal類的name變數 --Animal:動物 38 System.out.println(animal.name); 39 40 // 輸出Animal類的staticName變數 --Animal:可愛的動物 41 System.out.println(Animal.staticName); 42 43 // 輸出Cat類的eat()方法 --Cat:吃飯 44 animal.eat(); 45 46 // 輸出Animal類的staticEat()方法 --Animal:動物在吃飯 47 Animal.staticEat(); 48 49 // 呼叫Cat類的str變數 --Cat:可愛的小貓 50 System.out.println(cat.str); 51 52 // 呼叫Cat類的name變數 --Cat:貓 53 System.out.println(cat.name); 54 55 // 呼叫Cat類的eatMethod()方法 --Cat:貓喜歡吃魚 56 cat.eatMethod(); 57 } 58 }
通過引用型別變數來訪問所引用物件的屬性和方法時,Java 虛擬機器將採用以下繫結規則:
- 例項方法與引用變數實際引用的物件的方法進行繫結,這種繫結屬於動態繫結,因為是在執行時由 Java 虛擬機器動態決定的。例如,animal.eat() 是將 eat() 方法與 Cat 類繫結。
- 靜態方法與引用變數所宣告的型別的方法繫結,這種繫結屬於靜態繫結,因為是在編譯階段已經做了繫結。例如,animal.staticEat() 是將 staticEat() 方法與 Animal 類進行繫結。
- 成員變數(包括靜態變數和例項變數)與引用變數所宣告的型別的成員變數繫結,這種繫結屬於靜態繫結,因為在編譯階段已經做了繫結。例如,animal.name 和 animal.staticName 都是與 Animal 類進行繫結。
強制型別轉換
Java 編譯器允許在具有直接或間接繼承關係的類之間進行型別轉換。對於向下轉型,必須進行強制型別轉換;對於向上轉型,不必使用強制型別轉換。
例如,對於一個引用型別的變數,Java 編譯器按照它宣告的型別來處理。如果使用 animal 呼叫 str 和 eatMethod() 方法將會出錯,如下:
1 animal.str = ""; // 編譯出錯,提示Animal類中沒有str屬性 2 animal.eatMethod(); // 編譯出錯,提示Animal類中沒有eatMethod()方法
如果要訪問 Cat 類的成員,必須通過強制型別轉換,如下:
1 ((Cat)animal).str = ""; // 編譯成功 2 ((Cat)animal).eatMethod(); // 編譯成功
把 Animal 物件型別強制轉換為 Cat 物件型別,這時上面兩句編譯成功。對於如下語句,由於使用了強制型別轉換,所以也會編譯成功,例如:
1 Cat cat = (Cat)animal; // 編譯成功,將Animal物件型別強制轉換為Cat物件型別
子類的物件可以轉換成父類型別,而父類的物件實際上無法轉換為子類型別。因為通俗地講,父類擁有的成員子類肯定也有,而子類擁有的成員,父類不一定有。因此,對於向上轉型,不必使用強制型別轉換。例如:
1 Cat cat = new Cat(); 2 Animal animal = cat; // 向上轉型,不必使用強制型別轉換
如果兩種型別之間沒有繼承關係,那麼將不允許進行型別轉換。例如:
Integer i = 1; String s = (String) i; // 編譯出錯,不允許把Integer物件型別轉換為String物件型別
我們可以使用isinstanceof來判斷是否可以強制型別轉換:
1 public class TransType { 2 public static void main(String[] args) { 3 Object i = Integer.valueOf(1); 4 Animal animal = new Cat(); 5 if(animal instanceof Cat){ 6 Cat cat = (Cat) animal; 7 System.out.println(cat.name); 8 } 9 if(i instanceof String){ 10 String s = (String) i; 11 System.out.println(s); 12 }else{ 13 System.out.println("不能型別轉換"); 14 } 15 } 16 }