C# 入門指南
單元 11 - 建構子與屬性
建構子 (constructor) 是建立物件 (object) 時所執行的特殊方法 (method) ,屬性 (property) 則是封裝私有欄位 (field) 後,替私有欄位設定的存取子 (accessor)
「建構子」的英文原文為 constructor ,微軟官方文件提供的機器翻譯為「建構函式」,但是 C# 中只有類別,沒有函式的概念,事實上這個詞是用 C++ 的翻譯詞,因為 C++ 除了有函式的概念外,類別中與函式相仿的定義稱之為「成員函式」,實際上「成員函式」就是一般物件導向程式設計中所指的「方法」,這裡採用的是一般物件導向程式設計的翻譯詞「建構子」,由於跟微軟提供的官方文件有所不同,特此說明。
封裝 (encapsulation) 是物件導向程式設計 (object-oriented programming) 中的重要觀念之一,目的是保護欄位,不讓欄位直接被外界程式存取及修改,在 C# 中主要做法是將欄位宣告為 private ,也就是設定成私有欄位,例如
private int _seconds = 0;
_seconds 就是記錄總秒數的欄位。
以上私有欄位 _seconds 之前的底線是習慣上的寫法,目的是說這個欄位已被封裝,不加底線也是可以的。
這樣, _seconds 就只能在相同類別 (class) 中存取。
由於欄位已封裝,程式中如果要存取欄位就要定義屬性及存取子,例如
public int Minutes
{
get {return _seconds / 60;}
set {
_seconds += value * 60;
}
}
public int Seconds
{
get {return _seconds % 60;}
set {
_seconds += value;
}
}
這裡定義了兩個屬性, Minutes 及 Seconds 。 Minutes 中,關鍵字 get 定義的存取子是取得 Minutes 的方式,這裡是取得總秒數除以 60 的商
get {return _seconds / 60;}
關鍵字 set 定義的存取子是如果程式中設定 Minutes 之後的動作, value 是內容關鍵字,意思是指派運算子右邊的值,這裡將 value 乘以 60 ,再加入到 _second 中
set {
_seconds += value * 60;
}
內容關鍵字是在特定場合才具有關鍵字的效力。
至於 Seconds 雷同,基本上就是把總秒數 _seconds 用分及秒顯示。
以下寫成完整程式,將以上的定義放入 Timer 類別中,並在 Program 類別的 Main() 方法建立 Timer 物件
using System;
namespace ClassDemo02
{
class Timer
{
private int _seconds = 0;
public Timer(int s)
{
_seconds = s;
}
public int Minutes
{
get {return _seconds / 60;}
set {
_seconds += value * 60;
}
}
public int Seconds
{
get {return _seconds % 60;}
set {
_seconds += value;
}
}
}
class Program
{
static void Main(string[] args)
{
Timer t = new Timer(699);
Console.WriteLine("{0}:{1}", t.Minutes, t.Seconds);
t.Seconds = 10;
Console.WriteLine("{0}:{1}", t.Minutes, t.Seconds);
t.Minutes = 19;
Console.WriteLine("{0}:{1}", t.Minutes, t.Seconds);
}
}
}
//《程式語言教學誌》的範例程式
// http://kaiching.org/
// 專案:ClassDemo02
// 檔名:Program.cs
// 功能:示範 C# 的類別
// 作者:張凱慶
Main() 中建立 Timer 型態的變數 t 之後,再將變數 t 的 Seconds 設定 10 , Minutes 設定 19 ,這樣會連動替已封裝的 _seconds 增加秒數
static void Main(string[] args)
{
Timer t = new Timer(699);
Console.WriteLine("{0}:{1}", t.Minutes, t.Seconds);
t.Seconds = 10;
Console.WriteLine("{0}:{1}", t.Minutes, t.Seconds);
t.Minutes = 19;
Console.WriteLine("{0}:{1}", t.Minutes, t.Seconds);
}
執行結果如下
C:\ClassDemo02> dotnet run |
11:39 |
11:49 |
30:49 |
C:\ClassDemo02> |
以上介紹了與欄位相關的屬性,以及物件導向觀念中的封裝,物件導向還有其他兩個重要觀念,下一單元會繼續介紹。
相關教學影片
中英文術語對照 | |
---|---|
存取子 | accessor |
類別 | class |
建構子 | constructor |
封裝 | encapsulation |
欄位 | field |
物件 | object |
物件導向程式設計 | object-oriented programming |
屬性 | property |
方法 | method |
參考資料 | |
---|---|
1. C# 教學課程 | Microsoft Docs - 類別與物件 | |
2. C# 程式設計手冊 | Microsoft Docs - 類別和結構 | |
3. C# 程式設計手冊 | Microsoft Docs - 類別 | |
4. C# 程式設計手冊 | Microsoft Docs - 物件 | |
5. C# 程式設計手冊 | Microsoft Docs - 方法 |
重點整理 |
---|
1. 建構子是建立物件時所執行的特殊方法。 |
2. 封裝是將欄位宣告為 private ,這樣欄位就只限制在類別中的程式碼可以存取。 |
3. 封裝後的私有欄位要另外定義屬性及存取子存取,存取子用關鍵字 get 、 set 與 value 定義。 |
問題與討論 |
---|
1. 什麼是建構子?為什麼要有建構子? |
2. 什麼是封裝?為什麼要做封裝? |
3. 什麼是存取子?為什麼要定義存取子? |
練習 |
---|
1. 建立一個新專案 Exercise1101 ,替 Exercise1001 專案的 IntegerDemo 類別設計建構子及屬性。 |
2. 建立一個新專案 Exercise1102 ,替 Exercise1006 專案的 IntegerDemo 類別設計建構子及屬性。 |
3. 建立一個新專案 Exercise1103 ,替 Exercise1007 專案的 IntegerDemo 類別設計建構子及屬性。 |