在前一篇中,學會了如何使用屬性與封裝來保護資料,讓類別更安全也更有彈性。不過,目前我們建立物件的方式是:
Person p = new Person();
p.Name = "小明";
p.Age = 20;
這樣需要先「建立物件」,再逐一設定屬性,如果一個類別有很多屬性,這會顯得繁瑣。因此,C# 提供了建構子(Constructor) 與物件初始化器(Object Initializer),讓我們在建立物件時就能同時完成設定。
繼承 (Inheritance) 與封裝 (Encapsulation)、多型 (Polymorphism) 並列為物件導向程式設計三大特性。
以下範例展示了三個類別的繼承關係:
類別圖:
WorkItem 繼承 Object,新增了 6 個成員 (ID, Title, Description, jobLength, Update, WorkItem constructor)。
ChangeRequest 繼承 WorkItem,新增了 originalItemID 與自己的建構子。
// WorkItem 類別,繼承 Object
public class WorkItem
{
private static int currentID;
protected int ID { get; set; }
protected string Title { get; set; }
protected string Description { get; set; }
protected TimeSpan jobLength { get; set; }
// 預設建構子
public WorkItem()
{
ID = 0;
Title = "Default title";
Description = "Default description.";
jobLength = new TimeSpan();
}
// 帶參數的建構子
public WorkItem(string title, string desc, TimeSpan joblen)
{
this.ID = GetNextID();
this.Title = title;
this.Description = desc;
this.jobLength = joblen;
}
// 靜態建構子
static WorkItem() => currentID = 0;
protected int GetNextID() => ++currentID;
public void Update(string title, TimeSpan joblen)
{
this.Title = title;
this.jobLength = joblen;
}
// 覆寫 Object.ToString()
public override string ToString() =>
$"{this.ID} - {this.Title}";
}
// ChangeRequest 繼承 WorkItem
public class ChangeRequest : WorkItem
{
protected int originalItemID { get; set; }
public ChangeRequest() { }
public ChangeRequest(string title, string desc, TimeSpan jobLen,
int originalID)
{
this.ID = GetNextID();
this.Title = title;
this.Description = desc;
this.jobLength = jobLen;
this.originalItemID = originalID;
}
}
使用:
// 建立 WorkItem 物件
WorkItem item = new WorkItem("Fix Bugs",
"Fix all bugs in my code branch",
new TimeSpan(3, 4, 0, 0));
// 建立 ChangeRequest 物件
ChangeRequest change = new ChangeRequest("Change Base Class Design",
"Add members to the class",
new TimeSpan(4, 0, 0),
1);
// 使用 WorkItem 的 ToString()
Console.WriteLine(item.ToString());
// 使用繼承自 WorkItem 的 Update()
change.Update("Change the Design of the Base Class",
new TimeSpan(4, 0, 0));
// ChangeRequest 繼承了 WorkItem 的 ToString()
Console.WriteLine(change.ToString());
Output:
1 - Fix Bugs
2 - Change the Design of the Base Class