2012年3月14日 星期三

[Programming] 物件導向 (5) - 介面

什麼是介面 (interface) ?這個名詞有沒有很熟悉?還是覺得很陌生?還是覺得很熟悉常常聽到又不知道具體的意義是什麼?
我們常常在講的使用者介面 (user interface) 或人機互動 (human-machine interaction),從維基百科上已有具體的文字定義[1]:
簡單來說,就是一個能夠有效控制機器,或是從機器裡得到回應的空間。廣義來說,作業系統、程序控制器、重機械控制器、汽車方向盤和計速器…等,都算是使用者介面。
我個人是將它想像成人和機器互動的中間那一層,而人可以從中間那一層去控制機器,機器會透過中間那層來傳達讓人知道的訊息

那在物件導向程式設計裡,介面又代表什麼?
這裡所說的介面,並不是指「使用者點了什麼按鈕,然後程式就會執行什麼動作」的那種介面,這是被歸類在使用者介面的範圍裡,和OOP中的介面不一樣。
這裡所謂介面,指的是一種特別的抽象類別,裡面有一個(或一群)方法,讓不同物件實現這些方法的時候,能做不同的事
這是不是聽起來很熟悉?現實出來的效果是不是有點像多型?沒錯~它是一種多型的實現方式(請參考三相之力[4])。

定義講多了,就好像都在嘴炮理論一樣。我們來看一下實際的例子。
有一個類別圖如下。反正就是有一個系統設計者,丟了這樣的類別圖給你,要你做出一個interfaceAction的介面,然後讓Fighter和Archer這兩個類別可以實現它。
這就是介面的長相:
public interface interfaceAction {
    void Run();
    void Walk();
    void Jump();
    void Sit(); 
}
這是Java語法。其實C#、PHP等OO語言都差不多,而且這裡要注意的不是語言上的差異。
一個介面,這樣寫就算完成了。眼睛一看就會發現它沒有定義各個方法實際要做哪些事,就只是把方法名稱列出來而已,等其它類別來實現 (realize) 它

然後如果有其它類別要使用這個介面的時候,它就會這樣去做:
public class Fighter implements interfaceAction {
    public Fighter(){
        System.out.println("Fighter Creation!");
    }

    @Override
    public void Run(){
        System.out.println("Fighter running...");
    }
    
    @Override
    public void Walk(){
        System.out.println("Fighter walking...");
    }
    
    @Override
    public void Jump(){
        System.out.println("Fighter jump once!");
    }

    @Override
    public void Sit(){
        System.out.println("Fighter sitting!");
    }
}
這段程式第一行比較要注意的是,在Java裡要完成一個介面時,中間要掛implements關鍵字,然後在後面加interface的名稱。假如程式很複雜,需要implemets兩個以上的interface,那就把interface名稱用逗點隔開就行了。
然後,這個實現interfaceAction的類別,要逐一實現interfaceAction裡的每一個動作,不然基本上編譯器不會給過。然而,每個要implements interfaceAction的類別,裡面的方法動作可以不一樣,多型就這麼實現了。
基本上使用上就是如此。如果有其它類別,比方說是Archer類別,要實現interfaceAction,就用同樣的方法來實現介面,並且在要把interfaceAction裡的方法也都寫過一次。

你可以把它想像成一個使用者介面(像是遙控器的按鈕和面板),上面每個哪裡有幾個按鈕或哪裡顯示東西都是固定好的,然後把它接到不同的機器元件上面之後,它的按鈕動作和顯示出來的東西就不一樣。OOP的介面只是把這種概念實現出來而已。


啊?你說每個動作都一樣,重寫一遍太麻煩?那就不要用interface啊!
我這樣講並不是不負責任的說法,不過這是設計上的問題,下次再說。你在這裡只要先知道:實現interface的元件,必須把所有interface裡的方法都實現出來
也許你會在程式書上面看到「abstract和interface之間的比較」之類的章節[3],我不打算在這裡提。因為abstract和interface之間雖然行為上有這麼一點相似,但是它們的概念卻是大大的不同。我認為,直接從這兩種東西的原始定義來看程式和用法,會容易理解許多。



ref:
[1] User interface from Wikipedia
[2] Interface (computing) from Wikipedia
[3] Java Gossip: 介面(interface)型態
[4] [Programming] 物件導向(3) - 三相之力

沒有留言: