Java 中對象類型之間的類型轉換(前提是兩個類是父子關係)
1.向上轉型:把子類對象直接賦給父類引用,自動進行類型轉換。
靜態方法/成員變量(包括靜態變量和實例變量)同“父類引用”所聲明的類型的方法/變量綁定,例如,animal.staticEat()、animal.name 和 animal.staticName 都是與 Animal 類進行綁定。
使用向上轉型不能調用子類中特有方法和變量
使用向上轉型調用的是子類覆蓋或繼承父類的方法
2.向下轉型:將一個指向子類對象的父類引用賦給一個子類的引用,必須進行強制類型轉換(父類擁有的成員子類肯定也有,而子類擁有的成員,父類不一定有)。
向下轉型必須轉換為父類引用指向的真實子類類型,不是任意的強制轉換,否則會出現 ClassCastException
向下轉型時可以結合使用 instanceof 運算符進行判斷
向下轉型調用的是子類的方法和變量、可以調用繼承於父類的方法和變量
當我們使用經典多態寫法 Father f=new Son()時,如果子類和父類存在同名的成員變量和靜態變量時,是什麼情況呢?
class Animal{
static String name = "animal";
int num = 1;
public void run() {
System.out.println("animal run");
}
public static void sleep() {
System.out.println("animal sleep");
}
}
class Cat extends Animal{
static String name = "cat";
int num = 2;
public void run() {
System.out.println("cat run");
}
public static void sleep() {
System.out.println("cat sleep");
}
}
public abstract class test4 {
public static void main(String args[]) {
Cat cat = new Cat();
System.out.println(cat.num);
System.out.println(cat.name);
cat.run();
cat.sleep();
System.out.println("=================");
Animal animal = new Cat();
System.out.println(animal.num);
System.out.println(animal.name);
animal.run();
animal.sleep();
}
}
輸出結果如下所示
二、解釋靜態變量、靜態方法、成員變量來講,編譯看左,運行也看左。無論右邊是當前類還是當前類的子類,編譯和運行期間執行的都是當前類中的方法。非靜態方法,編譯看左,運行看右。也就是在編譯期間看左邊的類中有無該方法/屬性,而實際在運行時執行的是右邊類的方法/屬性。如果編譯期間沒有在左邊的類找到該非靜態域,則會報編譯錯誤。
上述問題的解釋:
static name: 此為靜態變量,運行都看左邊,所以cat輸出cat,animal輸出animalnum: 成員變量,運行看左邊,所以cat輸出2,animal輸出1run(): 非靜態方法,看右邊,cat和animal都使用Cat類的方法,即輸出cat runstatic sleep(): 靜態方法,看左邊,故cat輸出cat sleep,animal輸出animal sleep