天天看點

面向對象之多态(Java實作)

面向對象之多态

本文借鑒于csdn,部落格園,b站等各大知識分享平台

之前學習了封裝與繼承,封裝就是資料的封裝性(大緻了解),繼承就是一個類繼承另一個類的屬性,稱為父子類

多态

多态是面向對象的第三大特性(共三大特性)

求面積,對于不同的圖形有不同的求法。是以說,對于同一種行為,不同的事物可以展現出不同的形态。多态,描述的就是這樣的狀态。

定義:

多态是指同一行為,具有多個不同表現形式

多态的前提:

  1. 繼承或者實作【二選一】
  2. 方法的重寫【意義展現:不重寫,無意義】
  3. 父類引用指向子類對象【格式展現】

格式:

父類類型 變量名 = new 子類對象;
變量名.方法名();
           

注意:父類類型可以是子類對象繼承的父類,也可以是實作的父接口類型

代碼:

Fu f = new Zi();
f.method();
           

當使用多态方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,執行的是子類重寫後方法。

可能會覺得現在暫時的使用似乎沒什麼用處,那麼如何去正确的使用其這也就是接下來所要叙述的,多态的好處

實際開發的過程中,父類類型作為方法形式參數,傳遞子類對象給方法,進行方法的調用,更能展現出多态的擴充性與便利。

定義父類:

public abstract class Animal {
public abstract void eat();
}
           

定義子類:

class Cat extends Animal {
public void eat() {
System.out.println("吃魚");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭");
}
}
           

定義測試類:

public class Test {
public static void main(String[] args) {
// 多态形式,建立對象
Cat c = new Cat();
Dog d = new Dog();
// 調用showCatEat
showCatEat(c);
// 調用showDogEat
showDogEat(d);
/*
以上兩個方法, 均可以被showAnimalEat(Animal a)方法所替代
而執行效果一緻
*/
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat (Cat c){
c.eat();
}
public static void showDogEat (Dog d){
d.eat();
}
public static void showAnimalEat (Animal a){
a.eat();
}
}
           

由上面的代碼可以看出,showanimaleat方法的animal類型,是cat和dog的父類型,用它去接收子類對象,相當于用0-100去接洽0-10這是絕對可以收下的,因為夫類型肯定是比子類型要大

當eat方法執行的時候,多态規定,執行的是子類重寫的方法,那麼效果自然與showCatEat、showDogEat方法一緻,是以showAnimalEat完全可以替代以上兩方法。

不僅僅是替代,在擴充性方面,無論之後再多的子類出現,我們都不需要編寫showXxxEat方法了,直接使用showAnimalEat都可以完成。

是以,多态的好處,展現在,可以使程式編寫的更簡單,并有良好的擴充。

引用類型的轉換

多态的轉型分為向上和向下兩種

向上轉型

向上轉型:多态本身是子類類型向父類類型向上轉換的過程,這個過程是預設的。

當父類引用指向一個子類對象時,便是向上轉型。

使用格式:

父類類型 變量名 = new 子類類型();

向下轉型

向下轉型:父類類型向子類類型向下轉換的過程,這個過程是強制的。

一個已經向上轉型的子類對象,将父類引用轉為子類引用,可以使用強制類型轉換的格式,便是向下轉型。

使用格式:

子類類型 變量名 = (子類類型) 父類變量名;

為什麼要轉型

當使用多态方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤。也就是說,不能調用子類擁有,而父類沒有的方法。編譯都錯誤,更别說運作了。這也是多态給我們帶來的一點"小麻煩"。是以,想要調用子類特有的方法,必須做向下轉型。

為了避免ClassCastException的發生,Java提供了 instanceof 關鍵字,給引用變量做類型的校驗,格式如下:

變量名 instanceof 資料類型
如果變量屬于該資料類型,傳回true。
如果變量不屬于該資料類型,傳回false。
           

執行個體:

筆記本電腦(laptop)通常具備使用USB裝置的功能。在生産時,筆記本都預留了可以插入USB裝置的USB接口,但具體是什麼USB裝置,筆記本廠商并不關心,隻要符合USB規格的裝置都可以。

定義USB接口,具備最基本的開啟功能和關閉功能。滑鼠和鍵盤要想能在電腦上使用,那麼滑鼠和鍵盤也必須遵守USB規範,實作USB接口,否則滑鼠和鍵盤的生産出來也無法使用。

分析:

進行描述筆記本類,實作筆記本使用USB滑鼠、USB鍵盤

  • USB接口,包含開啟功能、關閉功能
  • 筆記本類,包含運作功能、關機功能、使用USB裝置功能
  • 滑鼠類,要實作USB接口,并具備點選的方法
  • 鍵盤類,要實作USB接口,具備敲擊的方法

實作

usb接口:

package cn.qioha.test2Interface;

public interface USB {
    public abstract void on();
    public abstract void off();
}
           

computer類

package cn.qioha.test2Interface;

public class Computer {
    public void switchOn(){
        System.out.println("打開計算機");
    }
    public void switchOff(){
        System.out.println("關閉計算機");
    }
    public void useDevice(USB usb){
        usb.on();
        if(usb instanceof Mouse){
            ((Mouse) usb) .click();
        }
        else if (usb instanceof Keyboard){
            ((Keyboard) usb).input();
        }
        usb.off();
    }

    public static void main(String[] args) {
        Computer c = new Computer();
        c.switchOn();
        c.useDevice(new Mouse());
        c.useDevice(new Keyboard());
        c.switchOff();
    }
}
           

keyboard類:

package cn.qioha.test2Interface;

public class Keyboard implements USB{
    @Override
    public void on() {
        System.out.println("開啟鍵盤");
    }

    @Override
    public void off() {
        System.out.println("關閉鍵盤");
    }
    public void input(){
        System.out.println("鍵盤輸入");
    }
}
           

Mouse類:

package cn.qioha.test2Interface;

public class Mouse implements USB{
    @Override
    public void on() {
        System.out.println("開啟滑鼠");
    }

    @Override
    public void off() {
        System.out.println("關閉滑鼠");
    }
    public void click(){
        System.out.println("滑鼠點選");
    }
}
           

ok,大緻就實作了,這裡還有很多的不足,接下來的更新我打算就更新問題即可,不再以回顧式樣的去更新部落格了,對自己的問題進行一個記錄反而是更好的

多有參考,僅供學習使用,麻煩見諒,侵權我立删!