java基礎篇之多型

@一葉之秋發表於2020-11-17

多型

一娘生九子,九子九個樣,生活中的多型。 動物,貓,狗,吃食物,貓吃魚,啃骨頭,動物界的多型。

1、java的多型
多型是java 物件導向的三大特徵之一。
是指同一行為,具有多個不同表現形式。這句話的缺點,未講清多型的結構。
屬於同一型別的不同的物件,在執行時其行為表現出不同的形態。
2、實現多型的例子
我需要一個狗的物件,程式碼就這樣寫:

Dog dog = new Dog();//這樣建立dog的物件並未體現出多型特徵
dog.eat();
   //如果是多型的寫法,程式碼就這樣寫:
Animal dog  = new Dog();
Animal cat = new Cat();
dog.eat();
cat.eat();

3 、多型的好處
主要是為了讓程式具有更大的擴充套件性。

public static void animalEat(Animal animal){
    animal.eat();
}
Dog dog  = new Dog();
Animal cat = new Cat();

animalEat(dog);
animalEat(cat);

Usb mouse = new Mouse();
Usb keyBoard = new KeyBoard();
public static void usbConnect(Usb dev){
    dev.connect();
}

3、實現多型的基本條件

  1. 繼承或者實現【二選一】
  2. 方法的重寫【意義體現:不重寫,無意義】,也包括介面方法的實現
  3. 父類引用指向子類物件【格式體現】
    4、多型的實現原理
    Java程式的執行過程中包含了兩個基本步驟,第一是源程式編譯成位元組碼檔案,第二是位元組碼檔案被JVM載入執行。因此java的程式就可以分為編譯期(源程式正在被編譯的過程中)和執行時(程式正在記憶體中執行)兩種狀態。
    (1)在編譯期,如果程式中建立了一個物件,編譯器會去確定物件的型別是什麼,比如:Dog dog = new Dog();編譯器只看前面的Dog dog,因此它認為dog物件的型別是Dog.Animal dog = new Dog();編譯器認為它的型別就Animal。
    (2)在執行時,Animal dog = new Dog();這行同樣的程式碼,執行器它判斷dog物件的型別看的是後面, new Dog(),因此執行時dog的型別是Dog();
    (3)在編譯器,只要是父型別所擁有的方法,都可以在物件上呼叫,因此,只要程式中呼叫的是父型別所擁有的方法,編譯器不會報錯。
    (4)編譯器會把編譯期所確定的物件的型別傳遞到執行時
    (5)在執行時,當物件執行方法時,因為執行器確定物件屬於子型別,因此執行的是子型別的方法,也就是為什麼宣告為Animal 型別的物件在執行的時候呼叫 的是Dog的方法。
    5、在多型情況下,屬於子類自已的方法將不能被執行。這是多型的缺點,但此缺點掩蓋不了多型的光茫。

6、引用型別的轉換
前面學習過基本型別的轉換,轉換的原則是弱型別轉強型別是自動轉換,強轉弱是強制轉換。
引用型別同樣存在型別轉換,它建立在繼承和實現的基礎之上,子型別轉換為父型別為自動轉換,相反,父型別轉換為子型別為強制轉換。
(1)Instanceof 語句,它用來判斷物件的實現型別。

boolean b = mouse instanceof Usb;//語句解讀,物件是某類的例項嗎?返回布林值
boolean b = mouse instanceof Mouse;//語句解讀,物件是某類的例項嗎?返回布林值
boolean b = mouse instanceof KeyBoard;//語句解讀,物件是某類的例項嗎?返回布林值

以上執行結果分別 是 true true false
以上程式碼說明mouse既是父親Usb的物件,也是自身Mouse的物件,但它與實現了同一介面的keyBoard只是兄弟關係,不具有繼承和實現的關係,因此mouse不可能是KeyBorder的物件.
(2)自動型別轉換
引用型別的變數的型別可以直接轉換為它的父型別或介面型別。自動轉換的語法是:直接把變數賦值給父型別的變數

    //把mouse轉換為 Usb型別
Usb m = mouse;
//其實底層作了一個判斷, mouse instanceof Usb;

(3)強制型別轉換
把父型別轉換為子型別,轉換語法:父型別 子型別物件變數 =(子型別)父型別的物件變數

    //把父型別轉換為子型別,可是子型別只能在執行時才能確定,編譯器報錯,因此要執行強制轉換
Mouse m = (Mouse)mouse;

7、向上轉型
用父型別宣告子型別的物件。把子型別轉換為父型別也就是自動轉換。
Animal dog = new Dog();
8、向下轉型
把父型別轉換為子型別的物件,屬於強制轉換。
這種情況可能會拋異常,把某種型別轉換為與它不相干的型別,在執行時會產生異常。

Usb mouse = new Mouse();
KeyBoard keyBoard = (KeyBoard) mouse;
keyBoard.connect();

java.lang.ClassCastException: com.wang.Mouse cannot be cast to com.wang.KeyBoard,在執行時丟擲型別轉換異常。原因在於,執行時會用
Instanceof 去判斷mouse物件是否屬於KeyBorder型別,如果結論是false則丟擲此異常。根源在於KeyBorder與Mouse不具有繼承和實現的關係。

相關文章