多態、向上轉型和向下轉型

多態性:

是對對象來說的。extends或implements是多態性的前提。

經理類繼承僱員類。小明是一個經理對象,這個對象既有經理形態,也有僱員形態。一個對象有多種形態,這就是對象的多態性。

多態性格式:父類引用指向子類對象

格式:父類名稱 對象名 = new 子類名稱();

或:接口名稱 對象名 = new 實現類名稱();

可以這樣理解:子類被當做父類來看待(一個經理被當做僱員來看待,一直貓被當做動物來看待)。而對象只能引用父類特有的方法。

多態訪問成員變量的兩種方式:

  • 直接通過對象名稱訪問成員變量:看等號左邊是誰,優先用誰,沒有則向上找。(編譯看左邊,運行還看左邊)

    Fu obj = new Zi();
    System.out.println(obj.num);
  • 間接通過成員方法訪問成員變量:看該方法屬於誰優先用誰,沒有則向上找。(先看右邊子類中有沒有該方法,沒有則向上找)

多態訪問成員方法:

訪問成員方法的規則:看new的是誰,則優先用誰,沒有則向上找(編譯看左邊,運行看右邊)。

先看左邊父類中有沒有該方法,沒有則編譯不通過報錯,但運行時是看右邊子類方法,沒有則向上找。只用於成員方法,不適用於成員變量。

向上轉型和向下轉型

在Java中,對象變量是多態的。

Employee e;
e = new Employee(...);
e = new Manager(...);//Manager繼承Employee

這裏的Employee類變量可以引用Employee類對象和任何一個Employee類的子類。

在《JAVA核心技術卷一》P152的代碼中

Manager boss = new Manager(...);
Employee[] staff = new Employee[3];
staff[0] = boss;

Employee boss = new Employee(...);
Manager[] staff = new Manager[3];
staff[0] = boss;//錯誤!

boss是Manager類對象,staff數組是Employee類對象,所以staff可以和boss指向同一對象,且編譯器將staff[0]看成Employee對象。如果是下面這段代碼會報錯,因爲不是所有的僱員都是經理(類比double轉換int可能會損失精度)。

向上轉型一定是安全的,從小範圍轉向了大範圍(從小範圍的經理轉向大範圍的僱員,從小範圍的貓轉向大範圍的動物,類似於從小範圍的int轉向大範圍的double不會損失精度)。
對象的向上轉型其實就是多態寫法:

//格式:父類名稱  對象名  =  new  子類名稱();
//右邊創建了一個子類對象,把它當做父類看待使用
Employee  Manager  =  new  Manager()
//創建了一個經理對象,把它當做僱員來看待

向下轉型是一個【還原】的動作,但要保證對象一開始創建的時候 ,就是經理,才能由僱員向下轉型爲經理。(用instanceof關鍵字判斷前面的對象是不是後面的類型)

String c = (String)staff[1];
//會產生編譯錯誤,因爲String不是Employee的子類
  • 只能在繼承層次內進行類型轉換
  • 將超類轉換成子類(向下轉型)之前,應該使用instanceof進行檢查
  • 類型轉換不是一種好的做法,多態的對象向下轉型是爲了使用子類特有的方法,這種情況下應該檢查超類的設計是否合理,也許重新設計超類並添加相應方法纔是正確做法。儘量少用類型轉換和instanceof
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章