今天要學習的內容是C#的類別跟物件,而至於為何要學類別與物件呢?因為在寫程式時,如果只是單純用變數與函式來處理邏輯,很容易造成程式碼混亂、不易維護。物件導向(OOP, Object-Oriented Programming)讓我們可以把程式碼「模組化」,將資料(屬性)和行為(方法)封裝在一起,更符合現實世界的思維。
Class 定義的型別就是一種 reference type(參考型別),在程式執行時,如果宣告了一個 reference type 變數,這個變數一開始的值會是 null,除非用 new 建立一個物件實例(instance),或是把它指派成一個已經存在的、相容型別的物件。像是以下範例:
MyClass mc = new MyClass(); // 建立新物件
MyClass mc2 = mc; // 指派給另一個參考
物件會配置在 Managed Heap(受控堆積記憶體)上,變數只存放「物件的參考(位置)」而非物件本身,記憶體回收由 CLR 的 Garbage Collection (GC) 負責。
在 C# 中,類別的宣告方式是:
[access modifier] class ClassName
{
// Fields, properties, methods, events...
}
所以最簡單的一個宣告如下:
//[access modifier] - [class] - [identifier]
public class Customer
{
// Fields, properties, methods and events go here...
}
在 class 前面可以加上「存取修飾詞」來控制誰可以使用這個類別,常見的修飾詞有以下幾個:
類別 vs. 物件的差異:
建立物件的語法,使用 new 關鍵字搭配類別名稱,來建立物件:
Customer object1 = new Customer();
Customer
→ 類別名稱。new Customer()
→ 建立一個 Customer 類別的物件。object1
→ 變數,存放的是 物件的參考(reference),而不是物件本身。
當建立物件時,系統會在 Heap(堆積記憶體) 配置空間給這個物件,變數(例如 object1)只是存放「指向該物件的參考位址」。
Customer object2; // 沒有用 new
object2 只是一個空的參考,沒有實際物件。
複製參考
Customer object3 = new Customer();
Customer object4 = object3;
object3 和 object4 都指向同一個物件,所以修改 object3 的內容,object4 也會看到變化。
當我們建立一個類別實例時,通常希望它的 欄位(fields) 與 屬性(properties) 一開始就有合理的值。
在 C# 中,有幾種方法來初始化物件的資料:
欄位初始化器(Field Initializers),可以在欄位宣告時,直接給它一個初始值:
public class Container
{
// 預設容量為 10
private int _capacity = 10;
}
建構函式參數(Constructor Parameters)建構函式(constructor)負責在物件建立時執行初始化:
public class Container
{
private int _capacity;
public Container(int capacity) => _capacity = capacity;
}
呼叫時必須提供一個初始值:
var c = new Container(20); // _capacity = 20
📌 呼叫者可以決定初始值,增加彈性。
主建構函式(Primary Constructor,C# 12 新功能)可以直接在類別名稱後面加上參數,簡化語法:
public class Container(int capacity)
{
private int _capacity = capacity;
}
物件初始化器(Object Initializers)可用來在建立物件時,直接指定屬性的初始值:
public class Person
{
public required string LastName { get; set; }
public required string FirstName { get; set; }
}
var p = new Person() { FirstName = "Grace", LastName = "Hopper" };
required 修飾詞,表示該屬性必須被設定,如果沒有設定,會產生編譯錯誤。強制呼叫者在建立物件時,完整提供必要資訊。
繼承的概念:繼承(Inheritance)是物件導向程式設計 (OOP) 的核心特性之一,一個類別可以從另一個類別「繼承」資料(欄位、屬性)與行為(方法、事件),透過繼承,可以建立類別的「階層關係」。最基本語法就是在類別名稱後面加上 : BaseClass 表示繼承:
public class Manager : Employee
{
// Employee 的成員會被繼承過來
// Manager 可以新增自己的成員
}