天天看點

《面向對象的思考過程(原書第4版)》一1.8.1 接口

我們可以看到接口定義了對象之間通信的基本手段。每個類設計接口規格來保證對象能被正确執行個體化和操作。必須向對象提供的接口發送消息來使用對象暴露的任何行為。接口需要完整描述類與類之間的互動。在大多數面向對象的語言中,通路修飾符指定為public的方法屬于接口。

私有資料

為了實作資料隐藏,必須将所有屬性聲明為private。屬性絕不是接口的一部分。隻有public方法是類接口的一部分。将屬性描述為public破壞了資料隐藏這一概念。

我們回過頭看一個使用的例子;計算一個數字的平方值。在這個例子中,包括兩個接口:

如何執行個體化一個square對象。

如何傳遞給該對象一個值,并擷取傳回的平方值結果。

正如在本章前面讨論的一樣,如果使用者需要通路一個屬性,我們會建立一個方法(即getter,又稱為取值方法)來傳回該屬性值。然後使用者想要擷取該屬性值,隻需調用取值方法即可。在這種方式中,擁有該屬性的對象可以控制通路該屬性。這種控制非常重要,特别對安全、測試和維護而言。如果你可以控制對屬性的通路,當出現了問題,無需追蹤所有可能修改了該屬性的代碼片段,我們隻需要修改一個地方(即setter,又稱為指派方法)。

基于安全的原因,你需要防止不受控的代碼對諸如密碼和個人資訊等資料進行修改和擷取。

類接口與方法簽名

請注意類有接口,方法也有接口。不要混淆這兩個接口的概念。類的接口是公共方法。你使用方法的簽名來調用這些公共方法。方法的簽名主要由方法名和它的參數清單組成。稍後會詳細介紹方法簽名這一概念。

隻有公共屬性和方法被認為是接口。使用者通過類接口與對象互動時,不應該看到該對象任何内部實作的部分。任何被定義為私有的東西對使用者都是不可通路的,這些私有資源屬于該類的内部實作。

在之前的例子中,隻隐藏了employee類的執行個體的屬性。很多情況下,也應該隐藏某些方法,不作為接口的一部分。上節的求平方值的例子中,使用者不應該關心平方值是如何被計算出來的,隻要答案正确即可。我們可以修改實作,但不應該影響使用者的代碼。例如,提供該電腦的公司可以改變算法(很可能因為該算法更高效)而不會影響結果。

圖1-12使用了真實的對象示範了接口/實作範式,這裡沒有使用代碼。烤面包機需要電。為了得到電,烤面包機的插頭必須插到電源插座,電源插座就是接口。所有需要擷取電力的烤面包機需要實作一個插頭,要與電源插座規格适配。這是烤面包機和電力公司(事實上是能源行業)之間的接口。電力裝置會關心實際的實作,而烤面包機則無需擔心。事實上,對于所有面包機而言,電力實作可能是原子能裝置或本地發電機。基于這樣的模型,一個裝置隻要滿足接口規格,就可以擷取電力,如圖1-12所示。

我們再拿square類來舉例。假設你正在編寫一個計算整數平方值的類。你必須提供接口和實作,也就是說必須定義一種方式使使用者能調用并擷取平方值,也要實作計算平方值。然而,使用者不應該知道任何詳細的實作。圖1-13展示了一種實作方式。注意在該類圖中,加号(+)表示public通路修飾符,而減号(-)表示private通路修飾符。即你可以通過給方法指定加号簽名的方式來定義接口。

《面向對象的思考過程(原書第4版)》一1.8.1 接口

該類圖代碼如下:

《面向對象的思考過程(原書第4版)》一1.8.1 接口
《面向對象的思考過程(原書第4版)》一1.8.1 接口

  

注意該類中使用者唯一能通路的元素就是公共方法getsquare。該公共方法就是接口。求平方值算法的實作在私有方法calculatesquare中。請注意屬性squarevalue是私有的,因為使用者無需知道該屬性的存在。是以對象隐藏了一部分實作,隻暴露了使用者需要與之互動的接口。與使用該對象無關的細節則對其他對象是隐藏的。

如果要修改實作,比如你想使用語言内置的平方值函數,你不需要修改接口。下面代碼使用了java庫的方法math.pow,其提供了同樣的功能,但接口依然是calculatesquare:

《面向對象的思考過程(原書第4版)》一1.8.1 接口

使用者使用相同的接口會得到相同的功能,但具體實作卻變了。如果你編寫處理資料的代碼時可以利用這一點。例如,你可以把資料存儲從檔案轉移到資料庫中,而不必強制使用者改變任何程式代碼。如下

繼續閱讀