2010-09-16 43 views
5

我是一個新的程序員,所以請原諒這個問題的任何愚蠢,下面的代碼是如何封裝私人數據? -封裝在哪裏?

public class SomeClass 
{ 
    private int age; 

    public int Age 
    { 
     get { return age; } 
     set { age = value; } 
    } 

    public SomeClass(int age) 
    { 
     this.age = age; 
    } 
} 

我的意思是,與在屬性沒有限制邏輯或過濾邏輯,如何在上述代碼從如下因素一個不同 -

public class SomeClass 
{ 
    public int age; 

    public SomeClass(int age) 
    { 
     this.age = age; 
    } 
} 

是對第一代碼提供任何封裝在所有?

回答

8

它提供了一個封裝:它說:「有一個Age屬性,你可以獲取和設置,但我不會告訴你如何實現它。」

這不是很強大的封裝,但它確實保持與公共API的實現細節分開。在根本不改變公共API的情況下,您可以開始將年齡存儲在其他地方 - 在short兩個字段中,在某個地方的某個服務中,作爲long字段或其他內容的一部分。您可以將日誌記錄放在屬性中以查看它使用的頻率。您可以添加一個事件,在年齡發生變化時觸發(這是一個API更改,但不會破壞現有的呼叫者)。

編輯:有一點需要注意:儘管現在沒有做任何事情,但對的更改使得以後做的事情既是源代碼又是二進制兼容。將字段更改爲屬性是而不是向後兼容,無論是源代碼還是二進制形式。在大多數的情況下,它將是源兼容的,但不是二進制兼容的。在某些情況下,源代碼將不再構建。在更邪惡的(並且人爲的,無可否認)兩個版本都會建立起來,但具有不同的效果。

另外請注意,由於C#3,你可以很容易地作爲一個申報財產瑣碎作爲一個字段:

public int Age { get; set; } 

我有一個article about all of this提供更多的細節。

+0

...但它是通過任何手段 「保護」 我的私人數據?我認爲保護私人數據是封裝服務的一個重要目的:( – atiyar 2010-09-16 15:21:13

+1

封裝使您能夠保護您的私人數據,就像說:「當我用這把錘子敲擊這些岩石時,怎麼會發生什麼事?我以爲錘子是爲了建築「這只是一個工具,它不會強制你使用它。 – recursive 2010-09-16 15:27:42

+1

@Nero:它可以是關於數據......它可以是關於實現的細節,它們都是封裝的一部分。 – 2010-09-16 16:09:19

0

在您的第一個示例中,SomeClass.Age是一個屬性。 「支持」財產的領域是私人的。在你的第二個例子中,SomeClass.age是一個公共字段。雖然在很多情況下可能沒有區別,但在字段上選擇屬性可讓您在不更改API或類的「形狀」的情況下更改實現。也許你想在財產發生變化時做一些事情(堅持或通知) - 這對於一個領域來說是不可能的。

+0

你可以很容易地把該領域變成一個屬性;-) – 2010-09-16 15:18:36

+1

有差異。屬性不能作爲'ref'傳遞。字段不能被數據綁定。 – recursive 2010-09-16 15:28:24

2

這是一個空洞的例子。正如您已經正確指出的那樣,該物業似乎沒有做任何事情。

但它可以。例如,SomeClass可以對Age屬性的修改方式加以限制(例如,不要將年齡更改爲-2或823等錯誤值)。此外,SomeClass不需要在內部將年齡表示爲int。年齡可能是計算的結果(比如說從一個人的出生日期中減去今天的日期),或者它可以作爲另一種數據類型(比如一個字節,長或者雙)存儲在SomeClass中。

+0

這就是很多「可能」,男人。我正在詢問代碼,因爲它現在是「是」。因爲我看到很多代碼(不是專家的),就像我說的那樣,私人領域和公共財產沒有限制邏輯。是不是屬性應該提供某種封裝來保護我的私人數據?如果他們不這樣做,那麼這兩個代碼樣本之間是否有區別?多數民衆贊成在所有我問,因爲我沒有任何想法。 – atiyar 2010-09-16 16:01:13

+0

@Nero:我不知道你爲什麼說「不是專家」 - 在某些情況下,一個公開可寫,瑣碎的財產是正確的。它比公共領域還要好。 – 2010-09-16 16:10:10

+0

@Nero:是的,財產和公共領域之間的語義差異很小,但這並不重要。良好的軟件工程的重點不僅僅是編寫可行的代碼,它是編寫可理解和可擴展的代碼。因此,「可能」與「是」的含義一樣重要。 – joshdick 2010-09-20 13:17:03

2

我的意思是,在性質沒有限制邏輯或過濾邏輯,是如何從如下因素一個

它不是事實,你已經被或尚未實施的驗證邏輯上面的一個不同在這裏,封裝意味着沒有人可以直接訪問/修改你的私人數據。唯一可用的訪問是通過該財產。

使用底部代碼,任何人都可以引發異常並導致各種破壞,因爲他們可以對數據做任何他們想做的事情。

使用頂級代碼作爲其寫入允許這種相同的破壞,但在將來的任何時候,您都可以在屬性中實現限制邏輯,而無需爲此類的用戶修改API。

1

它封裝或封裝對私有變量age的更改。私人變量Age不能由外部調用者直接修改,只能通過給出的public方法修改。它正在設置一個接口,以便將來對age所做的更改不會中斷呼叫者。未來的好處是外部呼叫者,這就是爲什麼現在很難看到。

0

是第一個提供任何封裝的代碼嗎?

否(至少是您編寫的特定代碼)。

2段代碼幾乎相同。第一個與第二個不同(與編寫代碼相比)沒有提供任何有用的區別。

當使用獲取者和設置者時,可以限制訪問私有變量。這可能是一種封裝形式。

private int x 

public int getInt(String password){ 
if(password == 'RealPassword'){ 
    return x 
    } 
}