2012-08-15 67 views
68

可能重複:
Abstraction VS Information Hiding VS Encapsulation抽象VS封裝在Java中

我知道這個問題可能已經問上千次在這個論壇上,甚至網也充滿了很多的定義有關這些概念,但都聽起來相同,都使用相同的技術詞彙。例如下面的定義

封裝是一個綁定或包裝數據和操作數據代碼到一個單一的實體的過程。這使得數據不受外部接口和誤用的影響。考慮封裝的一種方法是作爲一種保護性包裝,防止代碼和數據被包裝外定義的其他代碼任意訪問。

我從上面的定義瞭解到,創建變量時,將它們標記爲private,併爲這些變量生成getter-setter,並使用object訪問這些getter和setter。這樣數據就隱藏在對象內部,只能通過對象訪問。 希望我是對的


抽象是抽象的Java中的工藝被用來隱藏某些細節,只顯示對象的基本特徵。換句話說,它處理對象(接口)的外部視圖。

現在這是我永遠困惑的部分。每當我想到抽象時,我想到的東西就是Abstract類(可能是因爲兩者都有Abstract關鍵字)。上面的定義說抽象意味着隱藏數據,只顯示需要的細節,但這正是我們已經在封裝中做的權利?那麼有什麼區別。我也沒有得到中對象的側視圖,它涉及對象的外部視圖。

有人可以請一些現實生活中的例子或一些程序化的例子,如果可能的話更多的光線。

回答

30

抽象是關於識別共同點並減少您必須在代碼的不同級別上使用的功能。

例如我可能有一個Vehicle班。 A Car將衍生自Vehicle,以及Motorbike。我可以詢問每個Vehicle輪子,乘客等的數量,並且該信息已被抽象並且從CarsMotorbikes被識別爲共同的。

在我的代碼,我可以經常只是通過普通的方法go()stop()等。當我後來添加一個新的車輛類型(例如Scooter)我的大部分代碼將繼續無視這一事實,並實施應對VehiclesScooter單獨擔心Scooter的特殊性。

65

OO Abstraction中一流水平的設計時,用的客觀隱藏實現複雜的如何的由API /設計/系統提供的功能得以實施,在一定意義上簡化了「接口」來訪問基礎實施。

該處理可以在抽象,這使得大的系統,而不增加的代碼和理解,在複雜性更高的層,以建立的日益「更高」水平(層)被重複。例如,Java開發人員可以利用FileInputStream的高級功能,而不必關心其工作原理(即文件句柄,文件系統安全檢查,內存分配和緩衝將在內部管理,並且對消費者隱藏)。這允許更改FileInputStream的實現,並且只要API(接口)與FileInputStream保持一致,則針對先前版本構建的代碼仍然可以工作。

同樣,設計你的類時,你會想從別人隱藏內部實現儘可能。

在Booch的定義,OO封裝通過Information Hiding實現,並且特別是圍繞隱藏內部數據(場/代表狀態成員)的一類實例擁有,通過強制執行在訪問內部數據以及防止對這些領域進行直接的,外部的改變,以及隱藏課程的任何內部實現方法(例如,通過使它們變得私密)。

例如,類字段可以由默認private,且僅當被要求這些外部訪問,將一個get()和/或set()(或Property)從類露出。 (在現代OO語言中,字段可被標記爲readonly/final/immutable,其甚至在班級內進一步限制變化)。

實施例,其中NO信息隱藏已經應用(不好的做法)

class Foo { 
    // BAD - NOT Encapsulated - code external to the class can change this field directly 
    // Class Foo has no control over the range of values which could be set. 
    public int notEncapsulated; 
} 

實施例,其中場封裝已經施加:不可改變/ constructor-的

class Bar { 
    // Improvement - access restricted only to this class 
    private int encapsulated; 

    // The state of Bar (and its fields) can now be changed in a controlled manner 
    public void setEncapsulatedField(int newValue) { 
     if (newValue < 100) { 
      encapsulated = newValue; 
     } 
     // else throw ... out of range 
    } 
} 

實施例只有初始化一個字段

class Baz { 
    private final int onlyValue; 

    public void Baz(int immutableValue) { 
     // ... can check that immutableValue is valid 
     onlyValue = immutableValue; 
    } 
    // Further change of `onlyValue` outside of the constructor is NOT permitted 
    // even within the same class 
} 

重新:抽象VS抽象類

Abstract classes是促進類之間的共同性的重用類,但其本身不能直接與new()被實例化 - 抽象類必須被繼承,並且僅concrete(非抽象)子類可能被實例化。 Abstractionabstract class之間可能存在的一個混淆之處在於,在OO的早期,繼承被更多地用於實現代碼重用(例如,具有關聯的抽象基類)。如今,composition is generally favoured over inheritance,並且有可用來實現抽象更多的工具,如通過接口,事件/代表/功能,特性/混入等

回覆:封裝VS信息隱藏

最近encapsulation是當確定哪些方法,字段,屬性,事件等到bundle成爲一個類時,通常也以更一般的意義使用。

引用百科:

在面向對象的編程語言的更多的具體設置中,概念用來表示任一種信息隱藏機構,捆紮機構,或兩者的組合。

例如,在聲明中「我已經封裝了數據訪問代碼到自己的類」封裝的解釋大致相當於Separation of Concerns本金(在S固體),和可以被認爲是重構的同義詞。


[1] 一旦你已經看到了Booch的encapsulation cat picture你永遠無法忘記的封裝 - 面向對象的分析與應用設計的P46, 第二版

+0

所以我們使用的Java API是一個抽象? – sras 2015-07-23 06:58:12

+0

是的,從較高層面來說,API確實爲消費者提供了一種更簡單的抽象方式,它完全沒有意識到其內部設計背後的潛在複雜性。 Java顯然是一種語言,具有許多相關的高級框架。然而,我更具體地相信,在OO設計[主要術語](https://en.wikipedia.org/wiki/Object-oriented_design)被創造出來之前,抽象更具體地指的是類級設計和分解而不是指框架或企業級設計。 – StuartLC 2015-07-23 07:23:34

40

簡單單詞: 您在決定執行什麼時做抽象。 你在隱藏你已經實現的東西時進行封裝。