一個關於成員變量的多態問題

首先看下面的代碼:

class Fu{
    int i = 10;
}
class Zi extends Fu{
    int i = 20;
}
class Test{
    public static void main(String[] args)
    {
        Fu test = new Zi();
        System.out.println(test.i);
    }
}

這是一個很常規的多態,父類引用指向子類對象,引用變量所調用的方法總是表現出子類方法的行爲特徵,按照這種思想,思維慣性,上面的代碼應該輸出的是20,但是這段代碼的輸出其實是10,在這裏先給出結論:

成員變量不具備多態性,通過引用變量來訪問其包含的實例變量,系統總是試圖訪問它編譯時類型所定義的成員變量,而不是運行時類型所定義的成員變量

什麼是編譯時類型和運行時類型?
Java中的許多對象(一般都是具有父子類關係的父類對象)在運行時都會出現兩種類型:編譯時類型和運行時類型,例如:Person person
= new Student();這行代碼將會生成一個person變量,該變量的編譯時類型是Person,運行時類型是Student。
Java的引用變量有兩個類型,一個是編譯時類型,一個是運行時類型,編譯時類型由聲明該變量時使用的類型決定,運行時類型由實際賦給該變量的對象決定。如果編譯時類型和運行時類型不一致,會出現所謂的多態。因爲子類其實是一種特殊的父類,因此java允許把一個子類對象直接賦值給一個父類引用變量,無須任何類型轉換,或者被稱爲向上轉型,由系統自動完成。

依據上面的結論,在這段代碼中Fu test = new Zi();執行完後形成了多態,編譯時類型和運行時類型不一致,所以System.out.println(test.i);這一句輸出的是test編譯時類型所定義的成員變量,也就是10。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章