第 6 課 · 約 14 分鐘 · ← 第 5 課
類與物件:帶行為的資料
類是圖紙;物件是按圖紙造出來的東西。類型別的變數持有指向那個東西的引用。三個概念:欄位裝資料,建構子完成初始化,方法做動作。
一個什麼都有類
class BankAccount
{
public string Owner; // 欄位:每個物件一份
public BankAccount(string owner) // 建構子:在 new 時執行
{
Owner = owner;
}
public void Print()
{
Console.WriteLine(Owner);
}
}
BankAccount acct = new BankAccount("Ada"); // 造它
acct.Print();
逐塊拆:public = 類外可見。建構子和類同名、沒有返回型別——它的職責是讓物件一出生就合法。new 分配記憶體並執行它。
每個物件都是自己的
class Dog
{
public string Name;
public Dog(string name) { Name = name; }
}
Dog a = new Dog("Ada");
Dog b = new Dog("Grace");
Console.WriteLine(a.Name);
Console.WriteLine(b.Name); // 兩個物件,兩個 Name——不共享
static:屬於類,不屬於物件
class Counter
{
public static int Total = 0; // 只有一份,全員共享
public static void Increment()
{
Total++;
}
}
Counter.Increment(); // 在類上呼叫——不需要物件
Counter.Increment();
Counter.Increment();
Console.WriteLine(Counter.Total);
你早就在用 static 成員了:Console.WriteLine、int.Parse、Math.Max——全是類上的方法,不涉及物件。經驗法則:工具方法和共享計數器用 static;"每個一份"的用例項。
屬性:長著公眾面孔的欄位
現代 C# 風格——自動屬性看起來像欄位,但它是正式成員,帶 get/set:
class Rectangle
{
public double Width { get; set; } // 自動屬性
public double Height { get; set; }
public double Area()
{
return Width * Height; // 不用寫 this. —— 默默補上
}
}
Rectangle r = new Rectangle { Width = 3, Height = 4 }; // 物件初始化器
Console.WriteLine(r.Area());
物件初始化器(new Rectangle { … })在構造後立刻設屬性——簡單的初始化不需要引數建構子。
this:名字撞車的時候
在例項程式碼裡,this 意思是"當前這個物件"。它的主業:區分引數和同名欄位:
class Dog
{
private string name;
public Dog(string name)
{
this.name = name; // this.name = 欄位;name = 引數
}
}
風格建議:欄位用 PascalCase(Name)或字首(_name),this. 就幾乎永遠用不上——一個程式碼庫選定一種慣例就好。
建構子出錯的樣子
只要你聲明瞭任何建構子,C# 就不再免費提供空的那個——new Person() 會報 CS1729。修法:要麼傳引數,要麼顯式補一個無參建構子。
現在就練
- 建一個
Book類:Title+Year自動屬性、雙引數建構子、返回"Title (Year)"的Describe()方法。造兩本書,各列印一次。 - 加一個 static 計數器
BooksCreated,建構子裡自增——證明兩個物件共享它。 - 下一課:第 7 課 — 繼承與介面。