封裝和抽象的區別是什麼?
01-27
在看代碼大全,McConnell說抽象讓我們忽略細節,在不同的層次上處理細節,封裝則是填補了抽象留下的空白。
對於抽象我還是能懂一點的,可是當和封裝在一起討論的時候,我就有點暈了,誰能詳細的解釋解釋?
以前畫過一張圖,希望有幫助:D

先解釋一下抽象和封裝:抽象: 抽象就是忽略一個問題中與當前目標無關的那些方面,以便更充分的注意與當前目標有關的部分,抽象不打算了解問題的全部,而是只選擇其中的一個部分,抽象包括兩個方面:過程抽象和數據抽象。封裝:就是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。
再做一些說明:
舉例來說明一下,比如相思鳥和烏鴉,我們在抽象時,我們忽略那些比如嘴不一樣,而我們只在意它們都是有嘴的:mouth;我們忽略它們羽毛顏色的不一樣,而只在意它們的羽毛是有顏色的:color;然後我們抽象出嘴、羽毛顏色等特點。然後我們通過抽象出的這些特點,將它們封裝成鳥類Bird,這就是封裝。在使用時,我們會通過封裝出的Bird類來給鳥類的屬性賦值,比如bird.mouth=尖嘴,bird.mouth=圓嘴,這樣我們又還原出鳥類的不同的特點,這正印證了題主的那句話「抽象讓我們忽略細節,在不同的層次上處理細節,封裝則是填補了抽象留下的空白」。定義類的時候往往同時完成了抽象和封裝。但概念上還是可以區分的

首先要理解幾點:
- 抽象是為了把使用和實現這兩個任務分開。比如,打開web瀏覽器上知乎這是個使用任務,至於網路傳輸內部使用IPv4還是IPv6這個具體實現任務由網路供應商負責。
- 抽象是為了實現模塊化、黑盒化;通過封裝來實現抽象。每個模塊或黑盒提供使用介面,但保留內部具體實現細節是封裝並對用戶隱藏的。比如,我上知乎需要用家用路由器(對我來說是個黑盒組件模塊),路由器一般提供網卡介面(RJ45介面),我上網只需要把網線查到網口裡。但這個路由器的內部具體實現細節(裡面使用了什麼晶元和電路設計)是對我隱藏並封裝起來的。
- 為什麼要通過模塊換、黑盒化等封裝手段來實現抽象?因為我不想自己寫的軟體是鐵板一塊,牽一髮動全身,給自己挖坑。試想,我現在不是在軟體公司寫代碼的研發員工,而是奧迪公司轎車製造的研發人員。如果我把一輛車設計為不可分割的一個整體,萬一某個小零件壞了,整輛車就都壞了。如果我把整輛車模塊化設計,萬一某個零件壞了,只需更換壞了的零件。模塊化之後,我還可以把生產零件的任務外包給第三方,只需要給出我需要的模塊(如,音箱系統)標準即可,至於第三方如何具體實現這個零件(如,用索尼還是鐵三角)我也不用關心。
再回到抽象和封裝的概念:
- 類的抽象:把一個類的使用(對外介面,由其他類或其他程序員使用)和這個類的具體實現(由開發這個類的程序員實現)分離開。
- 類的封裝:把類的具體實現封裝,並對用戶隱藏起來。這個過程就是類的封裝。
我最近也在看這本書。
你的這個問題的原文在書中的第5章,而在第6章作者有更詳細的介紹。雖然還是沒有直接給出抽象與封裝的直接定義。但是給出了它們關注的側重點不同。6.1節---抽象數據類型(ADT)ADT是指一些數據以及對這些數據所進行的操作的集合。
一個準則是,當我們在操作數據的時候,不應該用對象直接對數據進行訪問,我們應該使用與數據對應的那些操作去操縱數據。
而這些操作(子程序)如果對於外部可見,就是類的公開介面。而公開介面就是一種抽象,它避免了我們在數據結構的低層次上操縱數據。6.2節---良好的類介面下的小節---良好的封裝
封裝是一個比抽象更強的概念。抽象通過提供一個可以讓你忽略實現細節的模型來管理複雜度,而封裝強制阻止你看到細節。這兩個概念之所以相關,是因為沒有封裝時,抽象往往容易被打破。綜合6.1和6.2我們可以看到。
我們在定義一個類的時候,設計了類的數據成員(private),方法,並規定了哪些方法public,哪些方法private,這個過程本身既包括了抽象,也包括了封裝。如果一定要進行一個劃分,那麼將數據,方法整合到一個類裡面,並且希望使用者只使用方法去操作數據成員,而且希望哪些方法應該被類使用者調用,這就是是抽象。然後在此基礎上,物理上規定哪些成員為public,哪些成員為private,這就是封裝。所以作者說的,讓我們在不同層次上處理細節。我的理解是:
假如說有一個聚會人員名單,你使用一個queue來保存每一個報名者,那麼你對人員的增刪就需要對於這個queue來操作。這是具體的數據結構層次。如果你抽象為ADT,那麼使用者就對聚會人員這個對象直接add(某人),或者delete(某人)這樣的操作,使用者也不知道是用vector,還是queue,還是stack來存的。作者說的,封裝填補了抽象留下的空白。我的理解是:封裝保證了抽象想要達到的目的的實現。因為封裝在抽象的基礎上,規定了public,private強制規定了可見性。這就是填補了空白的意思。推薦閱讀:
※怎麼通俗的解釋COM組件?
※如何理解「面向對象編程的精髓在於將操作綁定在數據上」?
※類(class)能不能自己繼承自己?
※新手求教python 面向對象編程的一個問題?
