物件導向 - 封裝的好處 [類別Class的包裝 與 屬性Property的封裝]

  • 1242
  • 0
  • C#
  • 2020-07-22

什麼是類別?
為什麼要建立類別?簡單來說,就是要將資料做「分類(Classify)」,使每筆資料在茫茫的記憶體中能夠最快速地被找到。

什麼是封裝?
簡單來說,建立類別(Class)就是一種生成"包裝(Package)"的概念
把類別當作一種包裝容器,"裝進"它的欄位(Fields)、屬性(Properties)、方法(Methods)等。

宣告類別時,針對資料安全性的考量,我們會使用存取修飾詞,這就是一種"封閉"。
對於類別(Class) 與 類別成員(Class Members)設定存取修飾詞(Access Modifiers)可以控制外部對於此類別與其成員的使用:"外部是否能夠看到、設定?"。

[2020/07/22補充] 其實屬性(Property)的誕生,也是一種封裝的概念:
屬性就是一種"包裝(Package)".....用來"裝進"欄位(Field)的包裝容器;
"封閉"就是一種.....可以運用屬性的get與set來控制外部的設值與取值,通常會有以下幾種可能:

  1. 可以讓外部看到取值、但不能設值的唯讀屬性=>將set設定private存取修飾詞。
  2. 可以讓外部看到取值、也可以設值=>get, set默認宣告,不使用存取修飾詞。
  3. 若不想讓外部看到取值、設值,那麼直接使用存取修飾詞為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!