1. 程式人生 > 實用技巧 >Java面向物件程式設計-介面

Java面向物件程式設計-介面

第八章 介面

與介面有關的5中設計模式:

  • 定製服務模式:設計精粒度的介面,每個介面代表相關的一組服務,通過繼承來建立符合介面
  • 介面卡模式:當兩個系統之間介面不匹配時,用介面卡來轉換介面
  • 預設介面卡模式:為介面提供簡單的預設的實現
  • 代理模式:為介面的實現類建立代理類,使用者通過代理類來獲得類的服務
  • 標識型別模式:用介面來標識一種沒有任何行為的抽象型別
  • 常量介面模式:在介面中定義靜態常量,在其它類中通過import static語句引入這些常量

8.1 介面的概念和基本特徵

在Java語言中,介面有兩種意思:

  • 指概念性的介面,即指系統對外提供的所有服務。類的所有能被外部使用者訪問的方法構成了類的介面。
  • 指用interface關鍵字定義的實實在在的介面,也稱為介面型別,用於明確的描述系統對外提供的所有服務,它能夠更加清晰的把系統的實現細節與介面分離。

類實現介面的關鍵字為implements。

public class Camera implements Photographable{
    public void takePhoto{... ...};
}

這段程式碼通過implement關鍵字宣告Camera類實現了Photographable介面。

介面的特徵:

  • 介面中的成員變數預設都是public、static、final型別的。必須被顯式初始化。並且介面中只能含有public、static、final型別的成員變數。
  • 介面中的方法預設都是public、abstract型別的。
  • 在JDK8以前的版本中,介面只能包含抽象方法。從JDK8開始,為了提高程式碼的可重用性,允許在介面中定義預設方法和靜態方法。預設方法用default了宣告,擁有預設的實現。介面的實現類既可以直接訪問預設方法,也可以覆蓋它,重新實現該方法。
    • 介面中的靜態方法只能在介面內部被訪問,或者其它程式通過介面的名字來訪問它的靜態方法。
    • 在介面中為方法提高預設實現雖然可以提高程式碼的可重用性,但還是要謹慎地使用這一特性。
  • 介面沒有構造方法,不能被例項化。
  • 一個介面不能實現另一個介面,但它可以繼承多個介面。
  • 當類實現了某個介面時,它必須實現介面中所有抽象方法,否則這個類必須被定義為抽象類。
  • 不允許建立介面的例項,但允許定義介面型別的引用變數,該變數引用實現了這個介面的類的例項。
  • 一個類只能繼承一個直接父類,但能實現多個介面。

8.2 比較抽象類和介面

抽象類與介面都位於繼承樹的上層,它們具有以下共同點:

  • 代表系統的抽象層
  • 都不能被例項化
  • 都能包含抽象方法,這些抽象方法用於描述系統能提供哪些服務,但不必提及具體的實現
  • 從JDK8開始,不僅抽象類能夠為部分方法提供預設的實現,介面也具有這一特性。該特性可以避免在子類或者實現類中重複實現方法,這能提高程式碼的可重用性。

介面與抽象類的兩大區別:

  • 介面中的成員變數只能是static、public和final型別的,而在抽象類中可以定義各種型別的例項變數和靜態變數,這是抽象類的優勢所在,它可以包含所有子類的共同成員變數,避免在子類中重複定義。
  • 一個類只能繼承一個直接父類,這個父類可能是抽象類;但一個類可以實現多個介面,這是介面的優勢所在。

藉助介面,可以方便的對已經存在的系統進行自上而下的抽象。

介面中定義了系統對外提供的一組相關服務,介面並不強迫它的實現類在語義上是同一種類型。

對於兩個不同的系統,通過介面互動比通過抽象類來互動能夠獲得更好的鬆耦合。

使用抽象類和介面的總的原則:

  • 用介面作為系統與外界互動的視窗。一方面,介面向使用者承諾系統能提供哪些服務;另一方面介面指定系統必須實現哪些服務。介面是系統中最高層次的抽象型別。
  • 由於外界使用者依賴系統的介面,並且系統內部會實現介面,因此介面本身必須十分穩定,介面一旦指定,就不允許隨意修改。
  • 用抽象類來定製系統中的擴充套件點。

8.3 與介面相關的設計模式

8.3.1 定製服務模式

當一個系統能對外提供多種型別的服務時,設計精粒度的介面,對服務精心分類,把相關的一組服務放在一個介面中,通過對介面的繼承,可以派生出新的介面,針對使用者的需求提供特定的介面。

8.3.2 介面卡模式

鬆耦合的系統之間通過介面來互動,當兩個系統之間的介面不匹配時,需要用介面卡把一個系統的介面轉換為另一個系統的介面。

介面卡模式有兩種實現方法:

  • 繼承實現方式:
  • 組合實現方式:組合關係比繼承關係更有利於系統的維護和擴充套件,而且組合關係能夠將多個源介面轉換為一個目標介面。所以,應該優先考慮用組合實現介面卡模式。
8.3.3 預設介面卡模式
8.3.4 代理模式:

代理類與委託類同樣的介面,代理類主要負責為委託類預處理訊息,過濾訊息及把訊息傳遞給委託類,代理類和委託類之間為組合關係。

8.3.5 標識型別模式

這種介面沒有任何方法,僅代表一種抽象型別,在JDK中,有兩個典型的標識型別介面:

  • java.io.Serializable:實現該介面的類的例項可以被序列化
  • java.io.Remote:實現該介面的類的例項可以作為遠端物件
8.3.6 常量介面模式

在一個軟體系統中會使用以下常量,一種流行的做法是把相關的常量放在一個專門的常量介面中定義。