簡體   English   中英

什么是接口與方法,C ++中的抽象與封裝

[英]what's interface vs. methods, abstraction vs. encapsulation in C++

當我和朋友討論時,我對這些概念感到困惑。

我朋友的意見是

1)抽象是關於純虛函數。

2)接口不是成員函數,但是接口是純虛函數。

我發現在C ++入門中,接口是數據類型支持的那些操作,因此成員函數是接口。

我的意見是

1)抽象是關於接口和實現的擴展;

2)成員函數是接口。

那么有人可以為我澄清這些概念嗎?

1)抽象,抽象數據類型和抽象類之間的區別。

2)接口和成員函數之間的區別。

3)抽象和封裝之間的區別。

我認為您的主要問題是您和您的朋友對“接口”一詞使用了兩種不同的定義,所以你們都以不同的方式正確。

您每天都在使用“接口”來定義“與某物進行互操作的定義方式”,例如“我的計算機和鍵盤之間的接口是USB”或“真空和牆壁電源之間的接口是一個出口。” 從這個意義上講,是的,方法(甚至是具體的方法)是接口,因為它們定義了與對象進行互操作的方式。 這並不是說它不適用於軟件,而是術語“應用程序編程接口(API)”中使用的“接口”。

您的朋友在面向對象的編程術語中使用“接口”,即“一個類可以選擇以保證它將支持的一組單獨定義的操作”。 在此,“接口”的定義特征是它沒有自己的實現。 應該通過提供接口定義的方法的實現來支持一個接口。 由於C ++在這種意義上沒有明確的接口概念,因此等效構造是僅具有純虛函數(又稱為抽象數據類型)的類。

另一方面,“抽象”是關於很多事情的,而且你們倆都是對的。 一般意義上的抽象意味着能夠專注於較高級別的概念,而不是較低級別的細節。 封裝是一種抽象,因為其目的是隱藏類方法的實現細節。 實現可以更改,而無需更改類定義。 純粹的虛函數(OO術語中的“接口”)是另一種抽象類型,因為如果正確使用它們,它們不僅可以隱藏實現,而且可以隱藏真正的基礎對象類型。 只要兩種類型都實現相同的接口,使用的類型就可以更改。

相同的術語可用於不同的事物,這就是在這里發生的事情。

C ++中的“抽象”是指根本沒有實現的方法(您無法使用抽象成員實例化一個對象。)

“抽象”只是“建模”的概念。 建模通過忽略一些細節使復雜的事物看起來更簡單。 在編程中,您希望將操作和概念分解為多個組件,並為每個組件抽象出不影響當前組件操作的外部組件的詳細信息。

編程“接口”是實現“抽象”的一種方式。 而不是擁有組件的所有源代碼和內部操作,您只會看到與您如何使用對象有關的操作。 通過將類上的所有方法標記為“抽象”(也稱為“純虛擬”)來實現C ++中的“接口”。這是通過在方法聲明之后但在分號之前放置“ = 0”來實現的。 該方法必須標記為“虛擬”才能合法。

換句話說,抽象的C ++類是至少具有一個純虛方法的類,並且通過使所有成員函數成為純虛的方法在C ++中實現了接口。

封裝是一個模糊的術語,但對我而言,它意味着一種實現抽象的技術。 這意味着“信息隱藏”。 您正在隱藏對象如何執行其“合同”的內部細節。 合同通過接口表達,我認為這是一種更強大的抽象形式。 任何具有受保護成員或私有成員的C ++類都使用封裝,但是僅實現純虛擬方法的類正在描述合同,承諾提供某些服務,而您對於這些服務的實現方式或同一對象可能提供的其他服務完全無需了解實行。

相同的對象可能會履行多個合同,並且通過公開多個不相交的接口,它不會強制客戶端知道該對象的所有輔助功能。 例如,一個對象可能能夠告訴您銀行帳戶余額,並且還可以序列化/反序列化到數據庫。 您可能只有一個類,所有這些操作都作為成員函數公開。 我更喜歡定義兩個接口“ IDatabaseSerializable”和“ IBankAccount”,並將適當的操作放在適當的接口中,並從實現類中的這兩個接口派生。 這樣,僅關心銀行余額的客戶將看到盡可能少的額外信息,而數據庫只會看到它關心的操作。

虛擬成員函數(不一定是純函數)與繼承相結合是表達C ++接口概念的一種方式 ,即接口和方法是正交的概念。

C ++中接口的另一種方法是使用通用代碼(即模板),您通常不希望任何具體類型-相反,您希望該類型具有具有某種語義的某些成員函數-如果不這樣,您將獲得一個編譯錯誤。

有人將其稱為“ 概念”,而您談到的是對特定概念建模的類型 雖然C ++並未正式支持概念,但是Boost.ConceptCheck之類的庫在提供替代項方面做得很好。

  1. 抽象意味着有人可以在不了解實現細節的情況下使用您的代碼。 使事情變得復雜的是,在一個上下文中作為實現細節的事物可能不在其他上下文中。 抽象數據類型是無法實例化的數據類型,僅描述其子類型的屬性。 抽象類只是某種抽象數據類型和類。

  2. 接口可以由一組成員函數隱式定義(盡管作為有用的抽象,這些成員函數至少應該是虛擬的,以便有多個可能的接口實現)。 也可以將其明確定義為僅具有純虛函數(在C ++中)或interface (在Java,C#和D中)的類。

  3. 抽象是當你不必知道的東西的實現細節。 封裝是當你無法知道它們。 例如,從OO角度出發,經過精心設計但又不麻煩將其成員變量設置為private仍然可以是有用的抽象,但不能進行封裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM