介面
介紹Java中interface的用法,及其物件導向意義。
何謂介面? What is Interface?
舉個現實中的例子,冰箱跟烤箱都是常見的電器設備,然而台灣電力公司要如何供給一般家庭所需的電力呢? 沒錯,就是110/220伏特的交流電,而且有一個標準的電力接頭,冰箱跟烤箱只需要接受這個電力規格,就可以使用,不管內部作了什麼處理,使用者只需要為他們接上制訂好的電源。
所以我們可以說,冰箱跟烤箱擁有相同的『行為』,在這裡指的就是接受並運用這個110/220伏特的交流電。
介面,描述不同類別的共通行為。
為什麼需要介面? Why Interface?
假設電器設備指的是可以從台灣電力公司取得需要的電源。
冰箱跟烤箱都可以接受台灣電力公司的電源,這兩個東西都可以視為電器設備,但這兩個東西在繼承關係上可說是相差很遠的。
例如:
物件 -> 冷藏設備 -> 冰箱。
物件 -> 加熱設備 -> 烤箱。
由於Java不允許多重繼承(任何類別只能有一個父類別),所以沒辦法讓冰箱既是冷藏設備又是電器設備。
無法多重繼承:
從現實中來看,冰箱跟烤箱只有『使用台電提供的電』這個共通的行為,因此我們把電器設備定義為介面,如此一來冰箱跟烤箱都可以『實作』這個介面,從而具有這個介面的特性,台電也很清楚的知道只要送出的電可以讓『電器設備』這個介面使用就好,任何需要電的設備只要符合這個介面制訂的規則,就可以獲得電力。
如此一來,冰箱就可以視為電器設備,當作電器設備來使用。
宣告介面 Declare interface
在Java中,我們可以把介面interface當成一種很特別的類別。
宣告方式:
範例程式:
介面的宣告就是使用關鍵字interface,跟類別很像都是走差不多的格式,其中方法的定義只能宣告『方法的原型』,就像在『抽象』的章節中提到的抽象方法一樣。
實作介面 implements interface
利用關鍵字implements,來讓類別實作某個介面,類別需要定義好該介面所制定的方法。
範例程式:
必須實作『所有』該介面宣告的方法,否則會編譯錯誤。
此時這個類別就可以被視為該介面來使用。
執行結果:
實作多個介面
在Java不允許多重繼承,但同一個類別可以實作多個介面,算是彌補了不能多重繼承所帶來的不方便。
實作多個介面用『,』隔開,寫上介面名稱,並且該類別必須實作每個介面所制定的方法。
使用格式:
範例程式:
內訂的修飾子
在interface中定義的欄位、方法都有規定好的修飾子,可以寫也可以不寫,但不能衝突。
介面方法的修飾:
程式設計師可以自己寫,但不能與之衝突。
介面欄位的修飾:
跟方法一樣,可以省略修飾子,但不能與之衝突。
介面欄位的存取
上面提到,可以在介面中宣告資料欄位並且修飾子限定是public static final,要如何使用呢?
嗯,就把介面當成一種特殊的類別,就是存取靜態欄位的方法。
程式範例:
執行結果:
要注意的是在介面中的欄位都是public static final的修飾,所以不能改變其值,一般都是當作該介面的常數來使用。
同名欄位的存取
一個類別可以實作多個介面,最多繼承一個類別,所以加上自己定義的欄位,可能會有許多相同名字的變數,該如何存取?
存取每個同名變數的範例程式:
執行結果:
同名方法的實作
一個類別可以實作多個介面,但介面中如果有相同的方法呢?
根據方法的多載,相同名稱、不同參數即視為不同的方法,一模一樣的方法實作一個即可,關鍵點是每個不同的方法都必須實作。
介面的繼承
沒錯,介面也可以繼承,而且還允許多重繼承!
彼此繼承的結果就是,實作該介面的類別必須實作每個定義的方法。
程式範例:
抽象類別實作介面
抽象類別也是個類別,當然也可以實作介面。
然而抽象類別中可以定義該介面宣告的方法的本體,也可以不定義。沒定義的話就是由繼承這個抽象類別的子類別要實作所有抽象方法。
程式範例:
原則就是,非抽象類別要實作所有未定義的方法。
抽象類別與介面的比較 Abstract Classes Compared to Interfaces
抽象類別與介面有點像,兩個都不行被實體化成物件。
抽象類別
用於被繼承,子類別要實作定義的抽象方法。
抽象類別中可以定義完整的方法(方法本體),也可以只定義方法原型。
可以定義完整的資料欄位供繼承類別使用。
設計中心以資料為主體。
介面
用於被實作,子類別要實作定義的方法。
介面中只能定義方法原型,不能有方法本體。
方法的修飾子必為public abstract,欄位的修飾子必為public static final,可省略不可衝突。
定義的資料欄位用於作為常數使用。(因為修飾子為public static final)
設計中心以方法(行為)為主體。
一般來說有共同的概念可以繼承相同的抽象父類別,
若只是行為相同以介面來設計會比較恰當。
實務上先考慮介面的劃分會比較方便,畢竟類別可以繼承多個介面,需要用到層層的欄位概念再使用類別去繼承。
Last updated
Was this helpful?