2011-02-11 133 views
7

可能重複:
difference between abstraction and encapsulation?抽象和封裝有什麼區別?

究竟什麼是Java封裝和抽象之間的區別?任何簡短的例子也將不勝感激。

+4

可能的重複:http://stackoverflow.com/questions/742341/difference-between-abstraction-and-encapsulation和http://stackoverflow.com/questions/3362335/difference-between-encapsulation-and-abstraction-概念 – 2011-02-11 07:47:27

+0

請更正問題標題中的錯字。乾杯 – 2011-02-11 07:54:08

回答

8

抽象和封裝是兩個偉大的口味,味道很好在一起。

封裝正在最小化您向您的代碼用戶公開的內容。該「用戶」可能是您的其他代碼,或者使用您發佈的代碼的人。

有一些明確的好處封裝:

  • 代碼的用戶不依賴於可能改變你的計劃的一部分。當你改變你的程序時,他們不必改變他們的代碼
  • 你更精確地控制你的代碼和狀態在程序的整個生命週期中的變化。你必須處理較少的場景,將有較少的意想不到的問題解決

我不知道Java的,但這裏是封裝在C#一個小例子:

public class Giraffe 
{ 
    public Giraffe(int heightInFeet) 
    { 
     this.heightInFeet = heightInFeet; 
     this.numberOfSpots = heightInFeet * 72; 
    } 

    public override string ToString() 
    { 
     return "Height: " + heightInFeet + " feet" 
      + " Number of Spots: " + numberOfSpots; 
    } 

    private int heightInFeet; 
    private int numberOfSpots; 
} 

反而暴露numberOfSpots的,它被封裝在類中,並通過ToString方法暴露。

抽象正在使用擴展點來讓選擇被推遲到運行精確代碼的不同部分。該選擇可以在程序的其他地方,另一個程序中或在運行時動態進行。

也有很大的好處,以抽象:

  • 當你改變你的代碼實現的抽象,抽象的用戶不必改變他們的代碼。只要抽象沒有改變,用戶就不必更改他們的代碼。
  • 當您編寫使用抽象的代碼時,您可以編寫一次代碼,可以對任何實現該抽象的新代碼重用。你可以編寫更少的代碼來做更多的事情。

C#中高度使用的抽象是IEnumerable。列表,數組,字典和任何其他類型的集合類都實現IEnumerable。該foreach環結構和LINQ庫的全部是基於抽象:

public IEnumerable<int> GetSomeCollection() 
{ 
    // This could return any type of int collection. Here it returns an array 
    return new int[] { 5, 12, 7, 14, 2, 3, 7, 99 }; 
} 

IEnumerable<int> someCollectionOfInts = GetSomeCollection(); 

IEnumerable<string> itemsLessThanFive = from i in someCollectionOfInts 
             where i < 5 
             select i.ToString(); 

foreach(string item in itemsLessThanFive) 
{ 
    Console.WriteLine(item); 
} 

您可以輕鬆編寫自己的抽象,過於:

public interface IAnimal 
{ 
    bool IsHealthy { get; } 
    void Eat(IAnimal otherAnimal); 
} 

public class Lion : IAnimal 
{ 
    public Lion() 
    { 
     this.isHealthy = true; 
    } 

    public bool IsHealthy 
    { 
     get { return isHealthy; } 
    } 

    void Eat(IAnimal otherAnimal) 
    { 
     if(otherAnimal.IsHealthy && !(otherAnimal is SlimeMold)) 
     { 
      isHealthy = true; 
     } 
     else 
     { 
      isHealthy = false; 
     } 
    } 

    private bool isHealthy; 
} 

IAnimal someAnimal = PullAnAnimalOutOfAWoodenCrate(); 

Console.WriteLine("The animal is healthy?: " + someAnimal.IsHealthy); 

您可以同時使用兩者,像我一樣與IAnimalIsHealthyIAnimal是一個抽象,並且只有一個get訪問器,並且IsHealthy上沒有set訪問器是封裝。

4

封裝是爲了保護您的成員變量或方法免受外界影響。

抽象是具體實現的方式。那就是用戶不知道使用哪個實現。

6

這兩個概念是完全不同的。

抽象是製作一個基類「抽象」,然後擴展其功能的做法。抽象類是在具體問題中不存在的東西;其唯一目的是延長。想想你是否正在編寫代表不同物種的課程。所有不同的物種都可能擴展一個抽象的動物類,因爲它們都將動物共享屬性。然而,你永遠不會實例化一個動物對象,因爲你在世界上看到的每一隻動物都是一隻松鼠,一條狗,一條魚......或者是這個抽象動物類的某種具體實現。

封裝是將您的類變量設爲私有的,然後允許從get和set方法訪問它們的做法。這樣做的目的是分開數據訪問的方式和實現方式。例如,如果你有一些變量有一個需求,那麼每次改變它時,它也會將第二個變量加1,然後封裝該功能;這樣你的代碼更加可靠,因爲每次訪問原始變量時都不必記住遵守該規則。

如果你想要特定的代碼示例,我建議只是做一個谷歌搜索,因爲有很多像這樣的例子。這裏有二:

http://www.tutorialspoint.com/java/java_abstraction.htm http://www.tutorialspoint.com/java/java_encapsulation.htm

3

封裝是抽象的一部分。抽象的概念是創建一個對象來表示另一個對象的概念。通常,原始對象比抽象更復雜。抽象因此是一種表現形式,通常作爲記憶的輔助手段,用於術語/交流等。可以這樣想:抽象藝術是其他事物的表現形式。方向盤,換檔器和2/3踏板是汽車工作原理的抽象。

基本上,抽象允許你表示一些複雜的東西,有很多細節,因爲它更簡單。在我看來,這與認知科學中的「分塊」有關。我們無法將複雜的東西放在腦海中,所以我們通過抽象來簡化,然後使用抽象。設計模式是另一個很好的例子。我們可以談論命令,狀態或戰略模式等,而不是談論細節。我們可以談論命令,狀態或戰略模式等。

封裝是形成/創建抽象的一部分。對象的界面越小,抽象就越容易。你不需要知道發動機和變速箱如何工作來駕駛汽車,你只需要瞭解它們的抽象(換檔和加速器)。引擎和齒輪箱的細節被封裝(進入界面)以創建抽象。

抽象需要封裝,因爲抽象不能處理所有真實的細節和複雜性(否則它不是抽象的)。所以變速箱是一個變速箱的不完整的代表(或模型),但它的日常使用足夠完整。封裝可以被認爲是「隱藏細節」,這對於創建更簡單的表示是必需的。

討論「接口」的概念也很重要。在大多數情況下,在這種情況下,「接口」和「抽象」這兩個術語的互換性更小。界面是用戶處理或交互的系統的一部分。與汽車的接口是方向盤,換擋和踏板等。抽象產生一個接口。你不直接處理引擎/變速箱,你處理它們各自的接口。

的另一個原因是封裝是因爲我們正在處理一個不完整的模型/抽象,我們不理解原文的全部複雜性,不能被信任來處理所有的變量(因爲我們不」瞭解完整的模型)。這對解耦非常重要,因爲如果沒有抽象,交互組件就會彼此瞭解太多。仔細想想,因爲每輛車都有方向盤,踏板和換檔裝置,無論發動機類型如何,您都可以駕駛任何汽車。同時,變速箱也從發動機中抽象出來。否則,每個定製引擎都需要一個定製變速箱。

同樣,一個類是一個抽象。該類通過其接口 - 該類的公共成員來表示一些複雜的模型。這個接口是通過封裝創建的。該課程向其合作者介紹了其更復雜實施的簡化界面。您也可以將其視爲「需要了解」情況。該班的合作者不需要確切知道它是如何工作的。正如你不需要知道引擎如何工作來駕駛汽車一樣。

封裝,接口和抽象在內聚和耦合以及維護代碼方面起着至關重要的作用。如果你沒有創建好的抽象概念,並且違反了「需要知道」的原則,那麼你的代碼會變得糾結,脆弱和變化的噩夢,因爲沒有「緩衝」。 「告訴別人問」的OO概念也與此有關。