天天看點

《C++面向對象高效程式設計(第2版)》——2.19 對接口的再認識

本節書摘來自異步社群出版社《c++面向對象高效程式設計(第2版)》一書中的第章,第2.19節,作者: 【美】kayshav dattatri,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

c++面向對象高效程式設計(第2版)

我們已經學習了接口在oop中的重要性,也了解了接口和實作之間的關系。每個對象都支援一組操作(消息或成員函數)。在聲明操作時,需要指定操作的名稱、被當做參數的對象,以及操作的傳回值。這就是之前提到的操作的簽名(或操作/函數的原型)。由對象操作定義的所有簽名的集合,稱為該對象的接口。

類型(type)是用于表示特殊接口的名稱,它使得接口易于管理。否則,接口之間就無法區分。如果一個對象支援定義在tint接口中的所有操作,則該對象的類型就是tint。一個對象可能有許多類型,換言之,一個對象可以支援(或響應)多個接口。如果兩個對象都支援相同的接口,則它們的類型相同,但兩者的實作可能完全不同。

是以,現在你可能認為,類隻不過是一個接口而已。在某些語言中,的确如此。但是,它們還是略有不同。有必要了解對象的類(class)和類型(type)之間的差別。對象的類定義如何實作對象,它定義對象的内部表示以及操作的實作。然而,對象的類型與實作無關——它隻涉及對象可響應的操作集合。一個對象可以有多種類型,不同的類可以有相同的類型。但是另一方面,類和類型的關系又十分密切。類清晰地定義了該類對象可執行的操作,是以,類也定義了對象的類型。類的任何對象都支援該類定義的接口。

在c++(和eiffel)中,類同時指定了對象的類型和它的實作。c++和eiffel都不能在類的外部定義接口。也就是說,接口隻能通過類指定1。類似java的語言,允許程式員無需依附任何類就能定義接口,類可以稍後實作一個接口(即類對象支援的接口)。在smalltalk中,程式員無需指定變量的類型。在運作期,将消息發送給對象時,必須經過檢查,以確定接收對象可實作該消息,但并不要求對象必須是某個特定類的執行個體。

經過以上的讨論,我們還要學習許多重要的課程。在實際應用中,最好是編寫僅依賴接口的軟體,而不是依賴特定實作的軟體。如果軟體不與任何特定實作綁定,一個接口可以由許多不同實作支援,那麼,在使用支援接口的新對象時,也不必時常更改軟體。這正是我們在軟體設計中力争達到的目标,軟體越獨立于實作越好。

有時,就算我們知道一些實作細節,也應裝作一無所知。即使實作做了改動(甚至是很大的改動),我們也不必為此擔心,因為接口仍保持不變。但是,在許多情況下,程式員會在程式中(有意或無意地)涉及一些實作的細節。當處理對象時,這樣的程式就非常依賴于特定的實作,遲早都會導緻設計和實作的重大變化。

從另一個方面看(即接口設計方面),接口不應該暴露實作細節。精心設計的接口不應該要求客戶了解實作的任何細節。如果在接口中暴露了某些實作細節(甚至是非常微小的),一些客戶就會期望獲得所有的實作細節,進而使得軟體非常脆弱,毫無穩定性可言。