iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
自我挑戰組

轉職仔自學Java筆記本系列 第 20

多型 Polymorphism

  • 分享至 

  • xImage
  •  

多型 Polymorphism 是借用了生物學的概念,代表著同一個物種可以有不同的型態、特徵。在物件導向的設計當中,就可以用父類別提供的方法呼叫,但各個子類別可以有不同的運算方式與結果。

再把水果家族請出來當例子吧。
https://ithelp.ithome.com.tw/upload/images/20231005/20162254Hr57SWwnxK.png

如果我們分別已經建好四個類別與繼承關係如下:

    // 水果 Fruits
    public class Fruits {
            public void eat(){
                    System.out.println("eating fruit...");
            }
            //...
    }

    // 葡萄 Grape
    public class Grape extends Fruits {
            public void eat(){
                    System.out.println("eating grape...");
            }
            //...
    }

    // 西瓜 Watermelon
    public class Watermelon extends Fruits {
            public void eat(){
                    System.out.println("eating watermelon...");
            }
            //...
    }

    // 檸檬 Lemon
    public class Lemon extends Fruits {
            public void eat(){
                    System.out.println("eating lemon...");
            }
            //...
    }

父與子類別有一個特性是「可以用父類別作為資料型別來宣告子類別」,也就是:

    Fruits fruits     = new Fruits();
    Fruits grape      = new Grape();
    Fruits watermelon = new Watermelon();
    Fruits lemon      = new Lemon();

    // 無論哪種水果都可以當作 Fruits 類

然而,雖然全部物件都宣告為 Fruits,但如果我們調用同一個方法 eat():

    fruits.eat();
    grape.eat();
    watermelon.eat();
    lemon.eat();

    // eating fruit...
    // eating grape...
    // eating watermelon...
    // eating lemon...

我們會發現到 grape, watermelon 與 lemon 調用的都是各自的 eat() 方法,而非 fruits 的 eat() 方法,這就是多型的概念「同一個類別但有不同的型態與行為」。

那多型實際上會帶來什麼好處呢?

第一個是可以把不同的類別放到同一個 Array, ArrayList …等。

先前有提到 Array, ArrayList在宣告時需指定元素的資料類別,所以不同類別無法放在同一個 Array, ArrayList 中。

    // 假設一個裝 Grape 的 ArrayList
    ArrayList\<Grape> basket = new ArrayList<>();

    basket.add(new Grape());
    // 可以放入 Grape

    basket.add(new Lemon());
    // 但無法放入其他的類別
    // java: incompatible types: Lemon cannot be converted to Grape

    // 如果改用父類別 Fruits 作為資料型別
    ArrayList<Fruits> basket = new ArrayList<>();
    basket.add(new Grape());
    basket.add(new Lemon());
    basket.add(new Watermelon());
    
    // 就可以把所有子類別都放到同一個 ArrayList 中

再來,如果子類別與父類別都有定義同一個方法,那定義一個操作父類別的方法就可以操作所有子類別

    // 如果定義一個 eatFruits 的方法,可以操作 Fruits 物件
    public void eatFruits(Fruits fruit){

         fruit.eat();

    }

    Fruits fruits     = new Fruits();
    Grape grape      = new Grape();
    Watermelon watermelon = new Watermelon();
    Lemon lemon      = new Lemon();

    // fruits 子類別的物件都可以當成參數使用
    eatFruits(fruits)
    eatFruits(grape)
    eatFruits(watermelon)
    eatFruits(lemon)

    // eating fruit...
    // eating grape...
    // eating watermelon...
    // eating lemon...


上一篇
繼承 Inheritance
下一篇
Abstract 抽象
系列文
轉職仔自學Java筆記本22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言