10.3 密封類與密封方法
如果所有的類都可以被繼承,那么很容易導致繼承的濫用,進而使類的層次結構體系變得十分復雜,這樣使得開發人員對類的理解和使用變得十分困難,為了避免濫用繼承,C#中提出了密封類的概念。本節將對類和方法的密封進行詳細介紹。
10.3.1 密封類概述及聲明
密封類可以用來限制擴展性,如果密封了某個類,則其他類不能從該類繼承;如果密封了某個成員,則派生類不能重寫該成員的實現。默認情況下,不應密封類型和成員。密封可以防止對庫的類型和成員進行自定義,但也會影響某些開發人員對可用性的認識。
C#中使用密封類時,如果類滿足如下條件,則應將其密封。
類是靜態類。
類包含帶有安全敏感信息的繼承的受保護成員。
類繼承多個虛成員,並且密封每個成員的開發和測試開銷明顯大於密封整個類。
類是一個要求使用反射進行快速搜索的屬性。密封屬性可提高反射在檢索屬性時的性能。
C#中聲明密封類時需要使用sealed關鍵字,具體語法格式如下。
訪問修飾符 sealed class 類名:
基類或接口
{
//類成員
}
說明:① 密封類不能作為基類被繼承,但它可以繼承別的類或接口。
② 在密封類中不能聲明受保護成員或虛成員,因為受保護成員只能從派生類進行訪問,而虛成員只能在派生類中重寫。
③ 由於密封類的不可繼承性,因此密封類不能聲明為抽象的,即sealed修飾符不能與abstract修飾符同時使用。
例10.8 下面代碼聲明一個密封類,該密封類中包含一個int類型的變量和一個無返回值類型方法,它們只能通過實例化密封類的對象來訪問,而不能被繼承。實現代碼如下。
public sealed class myClass //聲明密封類
{
public int = 0;
public void method()
{
Console.WriteLine("密封類");
}
}
10.3.2 密封方法概述及聲明
並不是每個方法都可以聲明為密封方法,密封方法只能用於對基類的虛方法進行實現,並提供具體的實現,所以,聲明密封方法時,sealed修飾符總是和override修飾符同時使用。
例10.9 下面代碼聲明一個類myClass1,該類中聲明一個虛方法Method,然后聲明一個密封類myClass2,該類繼承自myClass1類,在密封類myClass2中密封並重寫myClass1類中的虛方法Method。實現代碼如下。
public class myClass1
{
public virtual void Method()
{
Console.WriteLine("基類中的虛方法");}
}
public sealed class myClass2:myClass1
{
public sealed override void Method() //密封並重寫基類中的虛方法Method
{
base.Method();
Console.WriteLine("密封類中重寫后的方法");
}
}
說明:上面代碼中,密封並重寫基類中的虛方法Method時,用到了base.Method();語句,該語句表示調用基類中Method方法。base關鍵字主要是為派生類調用基類成員提供一種簡寫的方法。
10.3.3 密封類與密封方法的使用
密封類除了不能被繼承外,與非密封類的用法大致相同,而密封方法則必須通過重寫基類中的虛方法來實現。下面通過一個實例講解如何在程序中使用密封類和密封方法。
例10.10 創建一個控制台應用程序,其中聲明一個類myClass1,該類中聲明了一個虛方法ShowInfo,用來顯示信息。然后聲明一個密封類myClass2,繼承自myClass1類,在myClass2密封類中聲明兩個公共屬性,分別用來表示用戶編號和名稱,然后密封並重寫myClass1基類中的虛方法ShowInfo,並提供具體的實現。最后在主程序類Program的Main方法中實例化MyClass2密封類的一個對象,然后使用該對象訪問myClass2密封類中的公共屬性和密封方法。程序代碼如下
public class myClass1
{
/// <summary>/// 虛方法,用來顯示信息/// </summary>
public virtual void ShowInfo()
{
}
}
public sealed class myClass2 : myClass1 //密封類,繼承自myClass1
{
private string id = "";
//string類型變量,用來記錄編號
private string name = "";
//string類型變量,用來記錄名稱
/// <summary>/// 編號屬性///
///</summary>
public string ID
{
get{return id;}set{id = value;}
}
/// <summary>/// 名稱屬性/// </summary>
public string Name
{
get{return name;}
set{name = value;}
}
/// <summary>/// 密封並重寫基類中的ShowInfo方法///
/// </summary>
public sealed override void ShowInfo()
{
Console.WriteLine(ID + " " + Name);
}
}
class Program
{
static void Main(string[] args)
{
myClass2 myclass2 = new myClass2();
//實例化密封類對象myclass2.ID = "BH0001";
//為密封類中的編號屬性賦值
myclass2.Name = "TM"; //為密封類中的名稱屬性賦值
myclass2.ShowInfo(); //調用密封類中的密封方法}
}
}
運行結果為BH0001 TM。
10.4 小結
本章介紹了面向對象技術的高級應用,主要包括接口、抽象類、抽象方法、密封類及密封方法等內容。接口的存在可以使C#中存在多重繼承,這樣使得程序的結構更加合理;abstract關鍵字和sealed關鍵字分別實現了抽象和密封的定義,這兩種方法使得程序的設計更加嚴密。這里需要注意的是,在聲明密封方法時,必須通過重寫基類中的虛方法實現