什麼是類別?
為什麼要建立類別?簡單來說,就是要將資料做「分類(Classify)」,使每筆資料在茫茫的記憶體中能夠最快速地被找到。
什麼是封裝?
簡單來說,建立類別(Class)就是一種生成"包裝(Package)"的概念。
把類別當作一種包裝容器,"裝進"它的欄位(Fields)、屬性(Properties)、方法(Methods)等。
宣告類別時,針對資料安全性的考量,我們會使用存取修飾詞,這就是一種"封閉"。
對於類別(Class) 與 類別成員(Class Members)設定存取修飾詞(Access Modifiers)可以控制外部對於此類別與其成員的使用:"外部是否能夠看到、設定?"。
[2020/07/22補充] 其實屬性(Property)的誕生,也是一種封裝的概念:
屬性就是一種"包裝(Package)".....用來"裝進"欄位(Field)的包裝容器;
而"封閉"就是一種.....可以運用屬性的get與set來控制外部的設值與取值,通常會有以下幾種可能:
- 可以讓外部看到取值、但不能設值的唯讀屬性=>將set設定private存取修飾詞。
- 可以讓外部看到取值、也可以設值=>get, set默認宣告,不使用存取修飾詞。
- 若不想讓外部看到取值、設值,那麼直接使用存取修飾詞為private的欄位(Field)就可以了。
下面接下來,會為大家示例類別的裝與屬性的封裝,關於類別的封,因為內容較多,所以我會再另開一篇文章來做解釋。
<類別的裝>
假設說我今天建立的兩個類別:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public char Sexual { get; set; }
}
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
public char Sexual { get; set; }
}
你一定發現,這兩個類別的屬性都一模一樣,為什麼在程式運行建立物件之後,這些屬性能夠在茫茫的記憶體中快速地定位呢?
這其實就是建立類別的功勞,就把它想像成,記憶體中的每筆資料都被你做了很好地歸類。
以下這個圖片能夠幫你想像:每一個圓點就代表一筆資料(一個屬性),而相同顏色的圓點們,就代表它們隸屬同一個類別,所以即便是在茫茫的記憶體中,也能快速地被找到,這樣是不是就懂了呢?
<圖片來源>https://buy.line.me/product/320/pzKTyVPX
另外再說一說,為什麼我們要建立類別(建立模板),其實建立類別就像我們使用"蛋糕模具"做蛋糕一樣。
有做過蛋糕的人,一定都有用過蛋糕模具,所以你可以試想:雖然你每次都用這個模具(class)來做蛋糕,但是是不是每次做出來的蛋糕(Object)口味和樣子都不太一樣呢?所以使用模具,就跟建立類別是一樣的道理,就是想辦法在每個蛋糕(Object)的不同之處中,找到他們的相似之處,而它們的相似之處就是它們的製作過程都使用了一樣的模具來製作。
所以我也可以知道每一個蛋糕實體,都有它們的識別標籤,而這些標籤內的資料,就能表示每個蛋糕都是獨一無二的物件(Object)。
以下建立一個蛋糕模板(Cake class)來幫助大家了解。
class Cake
{
public string Ingredient { get; set; }
public int Size { get; set; }
public int Weight { get; set; }
}
我們能夠使用這個蛋糕模板,輕易的在程式世界中,產生不同的蛋糕物件,雖然每個物件都使用同樣的標籤,但卻能輕易地知道他們的不同之處,而且也容易地管理與查找資料。
[2020/07/22補充]
<屬性的封裝>
今天我們設定的主角為白雪公主SnowWhite,雖然這個童話主角應該存在有百年以上了,但我想要讓她永遠保有30歲,誰都不能改,請問該怎麼做呢?
class SnowWhite
{
private int _age = 30;
public int Age
{
get { return _age; }
private set { _age = value; }/* 將set設為private,不能透過外面設值 */
}
}
這樣一來就滿足了我的期望,外界永遠認定白雪公主為30歲,且誰都不能改。
那麼究竟get, set是如何形成的呢?
其實get, set本來是一對方法。
class SnowWhite
{
private int _age;
public int GetAge()
{
this.SetAge(30);
return _age;
}
private void SetAge(int value)/* 傳入參數 */
{
this._age = value;
}
}
有一對方法來讀取與寫入年齡,而微軟設定的value關鍵字,其實前身就是set方法的傳入參數,
微軟為了簡化程式碼,而有了以下的屬性寫法:(此屬性主要用於儲存資料,並沒有做一些邏輯實現,可以使用這種簡略宣告)
class SnowWhite
{
public int Age { get; private set; } = 30;
}
其實這種簡略寫法,看上去跟欄位宣告差異不大,但卻能實在地保護資料的安全性,將不願對外暴露的欄位資料封閉在屬性的包裝容器裡面,這就是物件導向 - 封裝的核心功能體現!
以上!我們下篇見!
如有敘述錯誤,還請不吝嗇留言指教,thanks!