JAVA:向上轉(zhuǎn)型和動態(tài)綁定機制

知識梳理

1.向上轉(zhuǎn)型的概念:
向上轉(zhuǎn)型又叫自動轉(zhuǎn)型、隱式轉(zhuǎn)型.向上轉(zhuǎn)型就是父類引用指向子類實例,也就是子類的對象可以賦值給父類的對象.

Animal dog = new Dog(); // Dog類是Animal類的子類

注:向上轉(zhuǎn)型是安全的,因為任何子類都繼承并接受了父類的方法.從例子中也可以理解,所有的狗都屬于狗的父類-動物,這是可行的,但是向下轉(zhuǎn)型則不行,若說所有的動物都是狗就不成立.(所以向下轉(zhuǎn)型要通過強制類型轉(zhuǎn)換,后續(xù)章節(jié)中會將解)
?
2.向上轉(zhuǎn)型的應(yīng)用
1)當(dāng)一個子類對象向上轉(zhuǎn)型父類類型以后,就被當(dāng)成了父類對象,所能調(diào)用的方法會減少,只能調(diào)用子類重寫了父類的方法以及父類派生的方法(如set(),get()方法),而不能調(diào)用子類特有的方法.

public class Animal{
   String name;
   int age;
   public Animal(){
    
   }
   public void eat(){
     System.out.println("animal吃東西");
   }

    public static void die(){
            System.out.println("animal死亡");
        }
}
public class Dog extends Animal{
      String favoriteFood;
       public void eat(){
           System.out.println("吃肉");
        }
        public void run(){
            System.out.println("夕陽下奔跑的小狗");
        }
        public static void die(){
            System.out.println("dog死亡");
        }
 }
public static void main(String[] args){
    Animal animal = new Dog();
    animal.age = 2;
    animal.name = "小強";
    animal.favoriteFood = "骨頭"; // 訪問子類的屬性報錯
    animal.eat(); // 調(diào)用的是子類的方法,輸出結(jié)果是"吃肉"
    animal.run();// 訪問子類特有的方法報錯
    animal.die();// 調(diào)用的是父類的方法,輸出結(jié)果是"animal死亡"
}

2)父類中的靜態(tài)方法時不允許被子類重寫的
如父類的有靜態(tài)方法die()
當(dāng)子類Dog中也定義同名方法時,此時die()算dog類自己獨有的方法:

  Animal animal = new Dog(); // 向上轉(zhuǎn)型
  animal.die();// 調(diào)用的是Animal類的die()方法,而不是調(diào)用Dog的die()方法
 // 輸出結(jié)果是:animal死亡

知識擴展

??多態(tài)的實現(xiàn)可以通過向上轉(zhuǎn)型和動態(tài)綁定機制來完成,向上轉(zhuǎn)型實現(xiàn)了將子類對象向上轉(zhuǎn)型為父類類型,而動態(tài)綁定機制能識別出對象轉(zhuǎn)型前的類型,從而自動調(diào)用該類的方法,兩者相輔相成.
動態(tài)綁定:
綁定就是講一個方法調(diào)用同一個方法所在的類連接到一起就是綁定.綁定分為靜態(tài)綁定和動態(tài)綁定兩種.

  • 靜態(tài)綁定:在程序運行之前進行綁定(由編譯器和鏈接程序完成的),也叫做前期綁定.
  • 動態(tài)綁定:在程序運行期間由JVM根據(jù)對象的類型自動判斷應(yīng)該調(diào)用哪個方法,也叫做后期綁定.
    靜態(tài)綁定的例子:
    ??如有一類Human,它派生出來三個子類Chines類,American類和British類,三個子類中都重寫了父類中的方法speak():void,在測試類中用靜態(tài)綁定的方式調(diào)用方法speak().
  Chinese c = new Chinese();
  c.speak();
  American a = new American();
  a.speak();
  British b = new British();
  b.speak();

這種調(diào)用方式是在代碼里指定的,編譯時編譯器就知道c調(diào)用的是Chinese的speak(),a調(diào)用的是American的speak().
動態(tài)綁定的例子:
如果我們在測試類中做以下改動:

// 生成父類對象數(shù)組,數(shù)組長度為5
Human[] human = new Human[5];
int n;
for(int i = 0; i < human.length;i++){
  n = (int)(Math.random() * 3); // 隨機產(chǎn)生從0到2中的一個數(shù)
  switch(n){
    case 0: human[i] = new Chinese();break;
    case 1: human[i] = new American();break;
    case 2: human[i] = new British();break;
  }
}
// 循環(huán)輸出,循環(huán)體中每個對象分別調(diào)用speak()方法
for(int i = 0;i < human.length;i ++){
  human[i].speak();
}

此時,Human類中隨機生成Chinese類,American類和British類的對象,編譯器不能根據(jù)代碼直接確定調(diào)用那個類中的speak()方法,知道運行時才能根據(jù)產(chǎn)生的隨機數(shù)n的值來確定human[i]到底代表哪一個子類的對象,這樣才能最終確定調(diào)用的是那個類的speak()方法,這就是動態(tài)綁定.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容