不學 JAVA 換學 C# 之覺得心累 - L1:ch9 類別和物件
前言
類別 (Class) 與物件 (Object) 是 C# 的基礎核心,基於物件導向程式設計 (OOP,Object Oriented Programming) 的特性,讓開發者能建立可重複使用且維護性高的程式碼。
物件導向
Class 類別
Class 類別是設計藍圖、模具或產品規格,它主要用來定義一個產品的特徵 (欄位 Field、屬性 Property) 和功能 (方法 Method)。
Object 物件、Instance 實例
利用產品規格產生出來的實品,每個實品可能有特徵或功能上的不同,但都是類別具體化後的表現。
簡單來說,Class 就是產品規格、Object 就是製作出來的實品。
建立類別與物件
建立 Class
類別包含欄位 Field、屬性 Property、建構式 Constructor 與方法 Method,定義了物件的狀態與行為,可使用不同的存取修飾詞控制存取範圍。
- 欄位 Field、屬性 Property:定義物件的狀態和特徵。(如:狗的品種、大小。)
- 建構式 Constructor:用於建立物件,產生基礎的物件狀態。(如:創造一隻狗的時候,它要被設定品種、大小和顏色。)
- 方法 Method:定義物件的行為。(如:狗的叫聲、奔跑方式。)
1 | // 存取修飾詞:public, class 保留字, 類別名稱:Dog |
建立 Object
是類別的實例 (Instance),是類別具體化後的表現。使用 new
關鍵字,搭配呼叫建構式實例化 (Instantiation) 物件:
1 | Dog lucky = new Dog("哈士奇", "中型犬", "黑白"); |
一旦 Object 被建立了,系統才會分配記憶體空間給 Object,用來儲存它的變動過的特徵以及執行功能後產生的一些結果。
建構式 (Constructor)
是一種特殊的函式,當你建立物件的時候,它會自動執行,用來初始化物件的屬性或執行一些設定,沒有回傳型態。
必須要有建構式,才能用 new
實體化物件,所以如果不寫建構式,C# 會自動提供預設建構式,也可以自訂。
預設建構式 (Default Constructor)
如果沒有定義建構式,C# 會提供一個隱藏的預設建構式 (不做任何初始化)。硬要寫出來的話是長這樣:
1 | // 存取修飾詞:public, 建構式名稱:Dog, 參數列表:() |
對應的實例化程式碼:
1 | // 實體化物件 |
複寫預設建構式
所有使用 new
實體化的狗,都會是哈士奇品種。
1 | public Dog() |
自訂建構式
但是記住,一旦 Class 中寫了一個以上的建構式,預設建構式就會消失。
1 | public Dog(string breed, string size) |
特殊且唯一的 C# 的類別
僅包含 Main()
方法的類別,是應用程式的進入點,請參考不學 JAVA 換學 C# 之覺得心累 - L1:ch0 程式架構。
封裝與存取修飾詞
C# 提供多種存取修飾詞來控制類別成員的可見性和存取範圍。這是用來保護一些,不想或不用對外暴露的資料和演算法邏輯。
public
:在程式的任何地方被存取。private
:只能在同一個類別內存取。protected
:只能在同一個類別內或其子類別內存取。internal
:只能在同一個組件 (assembly) 內存取。
通常實作上,我們會不希望欄位 (Field) 可以被直接修改,原因是:
- 封裝性 (Encapsulation):保護資料,不讓外部直接修改
當欄位是public
,任何外部的程式碼都能直接修改它的值,這可能會導致錯誤或不安全的資料操作。 - 控制存取權限 (Read-Only / Write-Only 權限)
有些時候,我們希望欄位只能被讀取,不能被修改,或只能被內部設定,不能被外部改變。 - 可以額外執行邏輯 (如:記錄變更日誌、計算等)
- 易於維護,未來可以修改實作方式
早期,我們會希望透過 GetXXX
or SetXXX
方法來取得或修改資料,範例:
1 | // 類別 |
但是如果有很多欄位,而且大部分都沒有額外的邏輯,就會變成寫很多類似的程式碼,這樣很沒有效率,中期就演變出屬性 Property,和欄位 Field 一樣名稱,差別僅開頭大小寫不同,然後可以這樣寫:
1 | // 類別 |
但是要寫的東西還是有點多,所以現在主要是使用自動實作屬性 (Automatically Implemented Properties)。