封裝(封閉)—讓你的隱私,屬於你個人
有乙個保護性的外殼或膜抱起來。
1.封裝意味著保證類中的一些資料是私有的。
★使用封裝來控制對類的方法和字段的訪問。
私有欄位和方法只能從類的內部訪問:
乙個物件要想得到另乙個物件私有欄位中儲存的資料,只有乙個辦法,就是使用返回該資料的公共欄位和方法。
相關問題:
❶問:我需要通過公共方法來訪問私有資料。但是如果包含私有欄位的類沒有提供獲取這個資料的方法,而我物件確實需要使用這個資料,會怎樣呢?
答:如果是這樣,則無法從這個物件外部訪問這個資料。寫乙個類時,一定要保證為其他物件提供了某個途徑來得到他們需要的資料。私有欄位是封裝的乙個很重要的部分,但是他並不是問題的全部。要便攜乙個封裝性很好的類,意味著要為其他物件提供乙個合理的、易於使用的途徑來得到他們需要的資料,而不允許他們非法接獲你的類本身需要的資料。
❷問:既然其他類無法訪問,為什麼還要保留這樣乙個欄位呢?
答:有時乙個類需要記錄一些必要的資訊來完成操作,但是其他物件確實不需要看到這些資訊。下面舉乙個例子。計算機生成隨機數時,會使用一些特殊的值,稱為種子。你不需要知道這是如何工作的,但是要知道random的每個例項實際上包含乙個資料,其中有十個數,random使用這個資料來確保next()總會提供乙個隨機數。建立random的乙個例項時,不會看到這個陣列。這是因為根本不需要他,倘若你能訪問這個陣列,就可以在其中放入一些值,這會導致生成非隨機的值所以種子對你完全是封裝的。
❸問:我用所有事件處理程式都有private這個關鍵字。為什麼他們都是私有的?
答:因為c#窗體要求只能由窗體上的控制項觸發事件處理程式。在方法前放上private關鍵字是,這個方法就只能在類內部使用。ide向程式增加乙個事件處理方法時,會把他宣告為私有,使得其他窗體或物件無法呼叫這個方法。但是並沒有明確的規定要求事件處理程式必須是私有的。實際上你可以自己做乙個檢查,雙擊乙個按鈕,然後把它的事件處理程式宣告為public。現在**應該仍能編譯並執行。
2.封裝的作用
封裝是指讓乙個類對另乙個類隱藏資訊。這有助於避免程式中出現bug。
★易於使用:
你已經知道了類使用欄位來跟蹤其狀態。另外,很多類使用方法來保證這些字段反映最新狀態,其他類根本不會呼叫這些方法。乙個類可能包含從未由任何其他類呼叫的字段、方法和屬性,這種情況很常見,如果將這些成員設定為私有,需要使用這個類時,這些成員就不會在智慧型提示視窗顯示出來。
★易於維護:
窗體直接訪問了乙個字段,而不是使用乙個方法來設定他。如果這個欄位是私有的,就完全可以避免這個bug。
★靈活:
很多情況下,你可能希望退一步,向之前的某個程式增加一些特性。如果你的類得到了很好的封裝,以後你就能清楚的知道該如何使用。
3,實現類封裝的幾個注意:
★考慮字段可能以何種方式被濫用。
★是不是類中所有一切都是公共的?
★哪些字段需要在設定時做一些處理或計算?
★只將必要的字段和方法宣告為公共。
4,封裝保證資料乾淨
有時程式正常完成工作時字段中的值會改變。如果沒有明確的告訴程式重新設定這個值,就會使用原來的值完成計算。對於這種情況,你可能希望一旦字段改變就讓程式執行一些語句,如每次改變就讓程式重新計算。通過使用自有字段封裝資料,可以避免這個問題。我們將提供乙個方法得到這個欄位的值,還會提供另乙個方法來設定這個字段,並完成所有必要的計算。
關於封裝的案例:
乙個farmer類使用乙個字段儲存使用乙個字段儲存奶牛數量,把奶牛數乘以某個數得出來餵養這些奶牛需要多少包飼料。
class farmer
public const int feedmultiplier;//農夫為每頭奶牛準備了30包飼料
public int getnumberofcows()
public void setnumberofcows(int newnumberofcows)
5.屬性使封裝更容易
可以使用屬性,這些方法對其他物件來說是字段。可以用屬性獲取或設定乙個後備字段,後備字段就是由屬性所設定的乙個欄位的名。
6,使用建構函式初始化私有字段
如果需要初始化物件,不過需要初始化的一些欄位是私有字段,那麼就不能使用物件初始化方法。幸運的是,任何類都能新增乙個特殊的方法,稱為建構函式。如果類有乙個建構函式,用new語句建立類時首先就會執行這個建構函式。可以向建構函式傳遞引數,為需要初始化的字段定值。不過建構函式沒有返回值,因為我們不會直接呼叫這個方法。要把它的引數傳入new語句。你已經知道了,new會返回物件。所以建構函式不會返回任何結果。
案例:
public
farmer(int numberofcows,int feedmultipler)
相關問題:
❶問:可以有不帶任何引數的建構函式嗎?
答:可以。類的建構函式沒有任何引數其實相當常見,實際上,你已經見過這樣的乙個例子:窗體的建構函式。檢視乙個新增加的windows窗體,找到他的建構函式宣告:
public
form1()
這就是窗體物件的建構函式,它沒有任何引數,不過必須完成很多任務作。構造方法中的
initializecomponent()方法會初始化窗體上的所有控制項,並設定這些控制項的所有屬性。如果在ide的窗體設計工具中將乙個新控制項拖到這個窗體上,並在properities視窗中設定它的一些屬性,就會看到這些改變將在initializecomponent()方法中反映出來。initializecomponent()方法在窗體建構函式內部呼叫,因此一旦建立窗體物件就會初始化所有控制項。
❷問:獲取或設定訪問方法中為什麼需要複雜的邏輯?不就是一種建立欄位的方法嗎?
答:因為要知道,有時每次設定乙個欄位時,都必須做一些計算或者完成一些動作。
❸問:方法與獲取或設定訪問方法方法之間有什麼區別呢?
答:沒有任何區別!獲取和設定訪問方法只是一種特殊的方法,對其他物件來說看上去就 像字段,設定該字段的時候就會呼叫。獲取訪問方法總是返回乙個與字段型別相同的值,而 設定訪問方法總有乙個名為value的引數,其型別與字段相同。對了,順便說一句,可以不 說「獲取和設定訪問方法」,而簡單的稱之為「屬性」。
❹問:那麼屬性中是不是可以有任何語句?
答:確實如此。方法中能做的,在屬性中也都可以做。屬性中可以呼叫其他方法、訪問其 他字段、甚至建立物件和例項。但是只有當訪問屬性時才會呼叫,如果其中的語句與獲取或設定屬性無關,那就沒什麼意義。
name = "dash martin";
public string
name}
如果建立乙個屬性,它只有設定訪問方法而沒有獲取訪問方法,那麼後備字段只能寫不能讀。
如果建立乙個屬性,他是有設定訪問方法而沒有獲取訪問方法,那麼後備字段只能寫不能讀。
public
string password
}}
實現封裝時,這兩種技術都很有用。
❼問:我使用物件已經有一段時間了,不過還沒寫過建構函式。這是不是說有些類不需要建構函式?
答:不是這樣的,這只是說明,如果沒有定義乙個建構函式,則c#會自動建立乙個無引數的建構函式,如果你定義了乙個建構函式,它就不再為你自動生成這樣乙個建構函式了,對於封裝來說這是乙個很有意義的工具,因為這表明你可以選擇讓例項化你的類的人使用你的建構函式。
▲注意:
屬性(獲取和設定訪問方法)是一中特殊型別的方法,只有在另乙個類讀寫乙個屬性才會執行。
Lua學習之Mac下封裝C模組
堅持 成長 每日一篇 平時用mac的同學可以看下,在mac下如何封裝乙個c庫給lua用,這兩天看了好多帖子都沒有成功打包,今天這裡做乙個詳細的教程,總結一下。首先我們寫乙個c檔案,如下 test.c include lauxlib.h include lualib.h include lua.h 待...
C 學習八之AES加密封裝
高階加密標準 英語 advanced encryption standard,縮寫 aes 在密碼學中又稱rijndael加密法,是美國聯邦 採用的一種區塊加密標準。這個標準用來替代原先的des,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高階加密標準由美國國家標準與技術研究院 nist ...
C 封裝學習(二)
物件陣列的例項。class coordinate int main 在用new申請陣列空間後,要用delete p來釋放掉記憶體,那為什麼要加呢。在申請乙個物件陣列時,分別呼叫了n次的建構函式,在釋放時也要呼叫n次析構函式,如果不加,那麼只銷毀指標指向的第乙個元素。在實際應用中,物件中包含物件是很常...