程序導向與物件導向程式設計
在類別出現之前,像是C語言,並沒有類別的概念。像C語言這種不存在類別、沒有物件的程式寫法,我們稱之為:程序導向程式設計。
程序導向程式設計:程式是一連串指令序列,核心目標是最佳化執行步驟
現在有了類別,就可以採用物件導向程式設計
物件導向程式設計:程式由多個封裝完成的類別所組成,核心概念是將資料 + 操作資料的函式包裝到邏輯相關的單元內,這個單元就是類別(class)。
類別的定義
類別是一種包含儲存資料、可執行程式碼的資料結構,內含兩類成員:
- 資料成員(Data Members) 存放物件屬性資料:欄位 (Fields)、常數 (Constants)
- 函式成員(Function Members) 實作物件行為邏輯:例如方法、屬性、建構函式、解構函式、運算子、索引子、事件
類別是封裝邏輯相關資料與函式的集合,用來對應真實世界或是抽象世界中的事物。
簡單來說,類別是由資料與函式所構成的資料結構,透過類別可以建立物件;我們可以透過物件存取資料與成員,在類別內部也能夠直接存取這些資料與成員。
類別的宣告
class 關鍵字僅用於定義類別樣板,不會建立物件執行個體;樣板包含三個部分:類別名稱、類別成員、類別特性。
語法
class 類別名稱
{
// 成員宣告(欄位、方法等,順序不強制規定)
}Code language: JavaScript (javascript)
類別宣告也常被稱為類別定義(class definition)
class Program
{
static void Main(string[] args)
{
AddCalculator addCalculator = new AddCalculator();
SubCalculator subCalculator = new SubCalculator();
}
}
class AddCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Add()
{
return A + B;
}
}
class SubCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Subtract()
{
return A - B;
}
}Code language: JavaScript (javascript)
上面範例宣告了兩個類別,一個實作加法運算、一個實作減法運算,接著在主程式Main函式當中建立它們的執行個體並使用。
本文內容來自 foxdevelop.com
類別宣告不一定要由上到下擺放,也就是你可以把類別宣告寫在後方,然後在前面的主函式呼叫,完全沒有問題。因為類別只是樣板藍圖,程式並不是由上往下循序執行;程式從Main函式開始執行,當需要某個類別時,才會去尋找對應的藍圖。

類別成員
欄位(Fields)
欄位是隸屬於類別的變數,可以是內建型別或是自訂型別,支援資料讀寫。
型別 欄位名稱;
class MyClass
{
int MyField; // int型別欄位MyField
}Code language: JavaScript (javascript)
和C/C++重要差異:C# 不存在全域變數,所有欄位必須宣告在型別(類別 / 結構)內。
欄位初始化規則
(1)隱性初始化(沒有指定初始值)
編譯器會自動指派該型別的預設值,不同型別對應的預設值各不相同。
int F1; // 預設 0
string F2; // 預設 nullCode language: JavaScript (javascript)
下表列出C#型別與欄位預設值對照。注意這是欄位的預設值;區域變數一定要由開發者手動初始化。
基本實值型別
| 資料型別 | 預設值 | 說明 |
|---|---|---|
sbyte | 0 | 有號 8 位元整數 |
byte | 0 | 無號 8 位元整數 |
short | 0 | 有號 16 位元整數 |
ushort | 0 | 無號 16 位元整數 |
int | 0 | 有號 32 位元整數 |
uint | 0 | 無號 32 位元整數 |
long | 0L | 有號 64 位元整數 |
ulong | 0UL | 無號 64 位元整數 |
float | 0.0f | 單精確度浮點數 |
double | 0.0d | 雙精確度浮點數 |
decimal | 0.0m | 高精確度十進位小數 |
char | '\0'(空字元,ASCII 0) | 單一字元 |
bool | false | 布林型別 |
列舉 Enum | 底層整數0對應之列舉成員 | 列舉底層為整數,預設0 |
結構 struct | 所有欄位各自使用預設值 | 自訂實值型別,整體歸零 |
參考型別
所有參考型別預設值統一為 null,代表沒有指向堆積裡任何物件。
意思就是沒有存放任何記憶體位址。回想前面繪製的記憶體示意圖:參考型別存放類似000001 01010這類堆積位址;如果是null,就代表沒有儲存任何有效記憶體位址。
| 型別分類 | 範例型別 | 預設值 |
|---|---|---|
| 內建參考型別 | string、object | null |
自訂類別 class | Person Student | null |
| 陣列(任意維度) | int[]、string[,] | null |
| 委派 / 事件 | Action、Func、自訂 delegate | null |
介面 interface | 任意介面變數 | null |
範例
string str; // 預設 null
Student jason; // 自訂類別,預設 null
int[] arr; // 陣列,預設 null
Action callback; // 委派,預設 nullCode language: JavaScript (javascript)
可為Null型別(Nullable / T?)
在基礎資料型別後面加上問號?,就會變成另一種型別,允許沒有有效值。前面提到int age; 不賦值預設是0;如果我們想要表達「完全沒有值」,就可以寫 int? age2;。age2就是可為Null型別,可以指定null:int? age2 = null;
可為Null型別是包裝後的ValueType,預設值為 null,代表「不存在有效數值」
| 宣告寫法 | 預設值 |
|---|---|
int? num | null |
bool? flag | null |
decimal? price | null |
class Test
{
int a; // 自動 = 0
string b; // 自動 = null
bool c; // 自動 = false
}Code language: JavaScript (javascript)
(2)顯性初始化
宣告時使用=指派初始值,指派的內容必須在編譯階段就能確定;不可以是隨機數值或是使用者輸入資料。
int days = 25;
string word = "foxdevelop";Code language: JavaScript (javascript)
(3)同型別多欄位簡寫
同一型別可以用逗號分隔批量宣告,不可以混合不同型別
int player, blood = 25;
string title, subTitle = "hi welcome to foxdevelop.com";Code language: JavaScript (javascript)
方法(Methods)
方法定義
方法是可重複使用、具備名稱的可執行程式區塊,對應C++的成員函式;呼叫後執行內部程式碼,執行完返回呼叫處,分成「有傳回值」與「無傳回值」兩種。
方法四大要素
- 傳回型別:沒有傳回值就寫
void - 方法名稱
- 參數串:沒有參數也要保留
() - 方法主體:
{}包覆執行程式碼
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
robot.SayHello();
}
}
class Robot
{
public void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
public void SayHello() 前方的public是修飾子,代表這個函式可以在類別外部存取(透過物件名稱.函式名稱)。如果沒有寫public,預設為private私有;私有函式只能在類別內部呼叫,即使使用robot這類物件名稱,外部也無法存取。

建立類別變數與執行個體
1. 參考型別基礎特性
類別屬於參考型別,記憶體分成兩塊區域:
- 堆疊 (Stack):存放參考變數(記憶體位址指標)
- 堆積 (Heap):存放物件真正資料
2. 分步建立物件
1 僅宣告參考變數(只配置堆疊記憶體,堆積沒有物件)
Robot robot;
// 只在堆疊配置參考空間,值未定義,堆積中不存在物件
Code language: JavaScript (javascript)

2 使用 new 運算子配置堆積記憶體
new 型別名稱();Code language: JavaScript (javascript)
- 在堆積配置記憶體,自動將所有欄位設為預設值
- 傳回堆積物件的參考位址,指派給堆疊變數
robot = new Robot();
Code language: JavaScript (javascript)

class Program
{
static void Main(string[] args)
{
Robot robot;
robot = new Robot();
}
}
class Robot
{
void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
3. 宣告與執行個體化一次完成
Robot robot = new Robot();Code language: JavaScript (javascript)
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
}
}Code language: JavaScript (javascript)
類別定義