什麼是OO?物件導向與多型

YC
程式愛好者
Published in
5 min readJul 28, 2020

這次我們要討論的是多型 (Polymorphism)。多型可能是最難以一些簡單言語加以解釋的概念,請各位在看下文時,多加思考在什麼的情境下,我們適合使用多型?

按照慣例,先上維基百科,讓我們來看看物件導向中的多型是指什麼 ?

多型指為不同資料類型的實體提供統一的介面。(撰自: 維基百科)

嗯嗯,這真是非常簡短且精闢定義,只是還是看不懂而已( ╯′ — ′)╯ ┻┻
讓我繼續以杯子為例子,介紹什麼是多型吧!

首先,繼承是多型能夠實現的必要條件 (可參考物件導向與繼承 ),而多型就是原有的類別提供一個上層介面抽象類別,而目的是為了消除了類別與類別之間的耦合性,使程式更容易維護與擴充

這就需要先了解什麼是介面與抽象層,為此我特意寫了篇文章介紹介面與抽象層的文章。 (物件導向中的介面與抽象類別是什麼?)

有了對介面與抽象層的了解後,我們只需要一點例子,大家就可以了解什麼是多型以及使用的時機。

abstract Class Cup {
abstract protected String getUse();
abstract protected int getPrice();
}
Class TeaCup extend Cup {

protected String getUse(){
return 'for tea';
}

protected int getPrice(){
return 50;
}
}
Class CoffeeCup extend Cup {

protected String getUse(){
return 'for coffee';
}

protected int getPrice(){
return 130;
}
}

如果現在我們有一個分析杯子的程式,我們可能會分別需要兩個分析不同杯子的 function,如下:

public String analysisTeaCup(TeaCup teaCup) {
if (teaCup.getUse() == 'for tea') {
return 'cup for tea';
}else{
return 'Not Tea Cup';
}
}
public String analysisCoffeeCup(CoffeeCup coffeeCup) {
if (coffeeCup.getUse() == 'for coffee') {
return 'cup for coffee';
}else{
return 'Not Coffee Cup';
}
}

但是我們可以運用多型來為我們多個類似的 function 做重構,如下:

public String analysisCup(Cup cup) {
if (cup.getUse() == 'for tea') {
return 'cup for tea';
}else if (cup.getUse() == 'for coffee'){
return 'cup for coffee';
}else{
return 'Not Tea or Coffee Cup';
}
}
TeaCup teaCup = new TeaCup();
analysisCup(teaCup); //'cup for tea'
CoffeeCup coffeeCup = new CoffeeCup();
analysisCup(coffeeCup); //'cup for coffee'

在上例中,我們使用抽象的 Cup 來作為 function 的參數,而不是分開兩個類別 (TeaCup, CoffeeCup) 來作為參數,所以我們只需要分別把繼承自 Cup 的類別的 Object 注入到 analysisCup() 中,就可以用同一個 function 來進行判斷。

這就是多型的力量,若然今天我們擁有的相似的類別有 30 個時,如不同牌子的汽車,我們絕對不希望為類似的商業邏輯創造分別 30 個 function,我們可以以多型為理念來創造一個通用的 function 給所有汽車類別使用。

同理地,我們也可以使用 interface 來作為多型的原材料,如下:

interface USB {    
public void execute();
public void stop();
}

Class Mouse implements USB {
private String state = 'stop';
private int countClick = 0;

public void execute() {
this.state = "start";
}
public void stop() {
this.state = "stop";
}
private void countClicking() {
this.countClick += 1
}
}

Class TestMouse
{
USB mouse = new Mouse();

public void startUSB(USB mouse){
if (mouse.state == 'stop') {
mouse.execute();
}
}
}

介面也可以使用在多型中,以介面為注入的類別,只要乎合介面,就可以被 function 所使用。還記得介面中的方法必須被實作這條規則嗎?當我們的 function 是想透過必須被實作的方法來作判斷時,以介面為多型就會變得超級好用!

至此,OO 三本柱,「封裝、繼承、多型」,我們已經全部介紹完畢,什麼是 OO 系列亦同時告一段落了,希望各位能時時思考 OO 的原則,我們在設計程式時又該如何去應用,這會是程式設計進步的不二法門。

如果你覺得我的文章幫助到你,希望你也可以為文章拍手,分別 Follow 我的個人頁與程式愛好者出版,按讚我們的粉絲頁喔,支持我們推出更多更好的內容創作!

--

--

YC
程式愛好者

提供更精確的技術內容為目標,另創立「程式愛好者」專頁。首席軟體工程師,專研後端技術、物件導向、軟體架構。