Java類——多態

一、多態性

\quadJava引用變量有兩個類型:一個是編譯時的類型,一個是運行時的類型,編譯時的類型由聲明該變量時的類型決定,運行時的類型由實際賦值給該變量的對象決定。如果編譯時類型和運行時類型不一致,就會出現所謂的多態。
\quad先看一個父類Base和子類Sub的代碼,根據其結果做進一步分析:

public class Base {
    public int book = 6;
    public void base() { System.out.println(1); }
    public void test() { System.out.println(2); }
}

public class Sub extends Base {
    // 重寫父類的test方法
    public String book = "Java瘋狂筆記";
    public void test() { System.out.println(3); }
    public void sub() { System.out.println(4); }
    public static void main(String[] args) {
        // 編譯時類型和運行時類型不同,多態發生
        Base ploy = new Sub();
        System.out.println(ploy.book);  // 6
        ploy.test();  // 3
        ploy.base();  // 1
        // 不能調用ploy.sub();
    }
}

\quadBase ploy = new Sub();這句話表明對象ploy編譯時類型是Base,而運行時是Sub。對於父類Base中沒有被子類覆蓋的方法,ploy得到的是父類的值,比如ploy.book=6, ploy.base=1;對於被覆蓋的方法,實際執行的就是子類中覆蓋掉父類方法,例如ploy.test=3是子類中被重寫後的打印值。這就是多態!
\quadJava允許把一個子類對象直接賦給一個父類引用變量,無需任何類型轉換,或者被稱爲向上轉型(upcasting),向上轉型由系統自動完成。
\quad當把一個子類對象直接賦給父類引用變量,例如上面的Base ploy = new Sub();對象ploy編譯時類型是Base,而運行時是Sub。當運行時,其方法行爲總是像子類的行爲而不是父類的行爲。這將出現相同類型的變量,執行同一個方法時出現不同的行爲特徵,這就是多態
\quad引用變量在編譯階段只能調用其編譯時類型所具有的方法,但運行時則執行其運行時類型所具有的方法。例如Object p = new Person()p只能調用Object類中的方法而不能調用Person類中的方法,但運行的時候首先看Person類中有沒有此方法,有的話運行Person類中的方法,沒有的話才運行Object類中的方法。
\quad與方法不同的是,對象的屬性不具備多態性。如上面ploy變量輸出book屬性時並不是輸出子類Sub的,而是輸出父類的屬性。

二、引用變量的強制類型轉換

\quadJava程序中引用變量只能調用其編譯時類型的方法,而不能調用其運行時類型的方法。如果要讓這個引用變量來調用它運行時類型的方法嗎,則必須把它強制類型轉換爲運行時類型,強制類型轉換需要藉助於類型轉換運算符。
\quad強制類型轉換語法很簡單:(type) variable,這種用法可以將variable變量轉換爲一個type類型的變量。
\quad引用類型之間的轉換隻能把一個父類變量轉換成子類類型,如果是兩個沒有任何繼承關係的類型,則無法進行類型轉換。即編譯時類型爲父類類型,運行時類型是子類類型。舉個例子:

public class TestConversion {
    public static void main(String[] args)
    {
        Object obj = "Hello";
        // obj變量的編譯類型是Object,是String類型的父類,可以進行強制類型轉換
        String objstr = (String) obj;
        System.out.println(objstr);
        // obj2變量的編譯類型是Object,是Integer類型的父類,可以進行強制類型轉換
        // 但obj2運行時類型是Integer,所以下面程序會觸發ClassCastException異常
        Object obj2 = new Integer(5);
        String obj2str = (String) obj2;
        System.out.println(obj2str);
    }
}

在這裏插入圖片描述
\quad考慮到進行強制類型轉換時可能出現異常,因此進行強制類型轉換之前應先通過instanceof運算符來判斷是否可以成功轉換。例如可將代碼改爲:

 if(obj2 instanceof String) 
 {
     String obj2str = (String) obj2;
     System.out.println(obj2str);
 }

三、instanceof運算符

\quadinstanceof運算符使用格式:引用類型變量 instanceof 類;
用於判斷前面的對象是否是後面的類,或是其子類的實例。如果是則返回true,否則返回false

public class TestInstanceof {
    public static void main(String[] args)
    {
        Object str = "Hello";
        System.out.println(str instanceof String);  // true
        System.out.println(str instanceof Object);  // true
        System.out.println(str instanceof Math);    // false
        // 下面程序無法編譯,運算符前面的數的編譯類型必須與後面的類相同或是後面類的父類
        // System.out.println((String)str instanceof Math);
    }
}
發佈了222 篇原創文章 · 獲贊 99 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章