================
@類型成員及其訪問限定
================
一個類型可以定義零或多個一下成員:
1、常數:常熟是一個表示恒定不變的值的符號,這些符號主要用來使得代碼更具有可讀性和可維護性。常數總是和類型而非它們的執行個體相關聯,它總是靜態。
2、欄位:欄位是類型的成員變數,它可以是唯讀或讀寫的。欄位又分為靜態和非靜態(執行個體欄位),靜態欄位被視為類型狀態的一部分,執行個體欄位被視為對象狀態的一部分。
3、執行個體建構函式:初始化新對對象的執行個體欄位。
4、類型建構函式:初始化類型的靜態欄位。
5、方法
6、重載操作符
7、轉換操作符
8、屬性:屬性是一種特殊的方法,它使得可以以一種簡單的、類似欄位的方式設定或擷取一個類型或對象的狀態,同時可以對其進行保護。
9、事件:事件分為靜態事件和執行個體時間。靜態事件通過類型發布通知,通知的接收者可以是一個類型,也可以是一個對象。執行個體事件通過對象發送通知,通知的接收者同樣
可以是一個類型或者一個對象。
10、類型:類型內部可以嵌套定義其他類型。
訪問限定修飾符和預定義特性
應用於類型、欄位、方法的訪問限定修飾符:
private 類型內部 + 嵌套類
protected 類型內部 + 嵌套類 + 衍生類別
Internal 程式集
protected internal 類型內部 + 嵌套類 + 衍生類別 + 程式集
public 全部
應用於類型的預定義特性:(兩者不可同時使用)
abstract 抽象類別(不能被執行個體化)。
sealed 終結類(不可作為基類)。
由於這兩者不可同時使用,如果要建立一個既不允許被執行個體化又不允許被繼承的類(比如 Math),就需要為該類指定一個 private 的構造方法。
應用於欄位的預定義特性:
static 靜態,類型的狀態。
readonly 唯讀。欄位僅可以在構造方法中被賦值
應用於方法的預定義特性:
static 靜態方法。不能訪問類型中的執行個體欄位或執行個體方法。
virtual 虛方法。當方法被調用時,無論對象是否被轉換為基底類型,都只有位於對象整合鏈最末端的方法被調用。僅應用於執行個體方法。
new 方法的子類實現不會重寫基類中的實現,而是將其隱藏。僅應用於虛方法。
override 顯式表明方法重寫了基底類型中的虛方法。僅應用於虛方法。
abstract 表示衍生類別型必須提供和該抽象方法簽名匹配的實現,否則衍生類別只能為抽象類別型。僅應用於虛方法。
sealed 衍生類別不能重寫該方法。僅應用於虛方法。
===========
@常數與欄位
===========
常數的類型必須是那些編譯器認為的基底類型,其總是被認為是類型(而非執行個體)的一部分,因此常數預設是靜態(static)的。
唯讀欄位可以是參考型別,且不會像常數那樣產生版本問題。執行個體唯讀欄位可以在建構函式中進行初始化。
======
@方法
======
1、執行個體建構函式:
在建立一個類型的執行個體時,系統將首先為該執行個體分配記憶體,然後初始化對象的附加成員(方法表指標和一個SyncBlockIndex),最後調用類型的執行個體建構函式進行初始化。
當構造一個參考型別的執行個體時,調用建構函式前,系統會將所有沒有顯示賦值的欄位賦予 0 值或 null。
一個類型的執行個體建構函式在調用其基類的繼承欄位之前,必須調用其基類的執行個體建構函式。C#編譯器會自動產生對基類預設建構函式的調用代碼。
2、類型建構函式必須指定為 static,且總是私人方式(無需指定 private)。
類型建構函式的調用時間:在類型第一個執行個體被建立之前,或者在類型的非繼承欄位或成員第一次被訪問之前(just before)或者之前的某個時刻。
類型建構函式不應該調用其基底類型的類型建構函式,因為基底類型的靜態欄位並沒有被衍生類別繼承,其方式是靜態繫結。
3、虛方法調用
【實驗步驟】
@定義常數欄位、唯讀欄位
///////////////////////////////////////////////////////////////////////////
// Test.cs
using System;
public class Test{
public static void Main(){
Console.WriteLine("num is : " + A.num);
}
}
// A.cs
public class A{
public const int num = 5;
}
///////////////////////////////////////////////////////////////////////////
D:\mytest>csc /t:library A.cs
D:\mytest>csc /r:A.dll test.cs
D:\mytest>test
num is : 5
刪除 A.DLL 檔案後仍可正常運行。
D:\mytest>test
num is : 5
但不可以編譯。
D:\mytest>csc /r:A.dll test.cs
error CS0006: 未能找到中繼資料檔案“A.dll”
將 A.cs 中 num 值修改為 10 重新編譯 A.cs。然後再運行:
D:\mytest>test
num is : 5
顯然這裡使用常數會產生版本問題,如果要獲得新的常數值必須重新編譯 test.cs。唯讀欄位能夠解決這個問題。
修改 A 的定義:
///////////////////////////////////////////////////
public class A{
public static readonly int num = 5;
}
//////////////////////////////////////////////////
重新編譯 A.cs 和 Test.cs 後運行:
D:\mytest>test
num is : 5
將 A.cs 中 num 值修改為 10 重新編譯 A.cs。然後再運行:
D:\mytest>test
num is : 10
刪除 A.dll
D:\mytest>test
未處理的異常: System.IO.FileNotFoundException: 未能負載檔案或程式集