理解C#編程中的靜態(tài)類(lèi)和靜態(tài)成員以及密封類(lèi)
靜態(tài)類(lèi)
靜態(tài)類(lèi)與非靜態(tài)類(lèi)基本相同,但存在一個(gè)區(qū)別:靜態(tài)類(lèi)不能實(shí)例化。也就是說(shuō),不能使用 new 關(guān)鍵字創(chuàng)建靜態(tài)類(lèi)類(lèi)型的變量。因?yàn)闆](méi)有實(shí)例變量,所以要使用類(lèi)名本身訪問(wèn)靜態(tài)類(lèi)的成員。例如,如果名為 UtilityClass 的靜態(tài)類(lèi)有一個(gè)名為 MethodA 的公共方法,則按下面的示例所示調(diào)用該方法:
UtilityClass.MethodA();
對(duì)于只對(duì)輸入?yún)?shù)進(jìn)行運(yùn)算而不獲取或設(shè)置任何內(nèi)部實(shí)例字段的方法集,靜態(tài)類(lèi)可以方便地用作這些方法集的容器。例如,在 .NET Framework 類(lèi)庫(kù)中,靜態(tài)類(lèi) System.Math 包含的方法只執(zhí)行數(shù)學(xué)運(yùn)算,而無(wú)需存儲(chǔ)或檢索特定 Math 類(lèi)實(shí)例特有的數(shù)據(jù)。就是說(shuō),通過(guò)指定類(lèi)名稱(chēng)和方法名稱(chēng)來(lái)應(yīng)用類(lèi)成員,如下示例所述。
double dub = -3.14; Console.WriteLine(Math.Abs(dub)); Console.WriteLine(Math.Floor(dub)); Console.WriteLine(Math.Round(Math.Abs(dub)));
輸出:
3.14 -4 3
和所有類(lèi)類(lèi)型一樣,當(dāng)加載引用靜態(tài)類(lèi)的程序時(shí),.NET Framework 公共語(yǔ)言運(yùn)行時(shí) (CLR) 將加載該靜態(tài)類(lèi)的類(lèi)型信息。程序不能指定加載靜態(tài)類(lèi)的確切時(shí)間。但是,可以保證在程序中首次引用該類(lèi)前加載該類(lèi),并初始化該類(lèi)的字段并調(diào)用其靜態(tài)構(gòu)造函數(shù)。靜態(tài)構(gòu)造函數(shù)僅調(diào)用一次,在程序駐留的應(yīng)用程序域的生存期內(nèi),靜態(tài)類(lèi)一直保留在內(nèi)存中。
靜態(tài)類(lèi)的主要特性:
- 僅包含靜態(tài)成員。
- 無(wú)法實(shí)例化。
- 是密封的。
- 不能包含實(shí)例構(gòu)造函數(shù)。
因此,創(chuàng)建靜態(tài)類(lèi)與創(chuàng)建僅包含靜態(tài)成員和私有構(gòu)造函數(shù)的類(lèi)基本相同。私有構(gòu)造函數(shù)阻止類(lèi)被實(shí)例化。使用靜態(tài)類(lèi)的優(yōu)點(diǎn)在于,編譯器能夠執(zhí)行檢查以確保不致偶然地添加實(shí)例成員。編譯器將保證不會(huì)創(chuàng)建此類(lèi)的實(shí)例。
靜態(tài)類(lèi)是密封的,因此不可被繼承。它們不能從除 Object 外的任何類(lèi)中繼承。靜態(tài)類(lèi)不能包含實(shí)例構(gòu)造函數(shù),但可以包含靜態(tài)構(gòu)造函數(shù)。如果非靜態(tài)類(lèi)包含需要進(jìn)行重要的初始化的靜態(tài)成員,也應(yīng)定義靜態(tài)構(gòu)造函數(shù)。
下面是一個(gè)靜態(tài)類(lèi)的示例,它包含兩個(gè)在攝氏溫度和華氏溫度之間執(zhí)行來(lái)回轉(zhuǎn)換的方法:
public static class TemperatureConverter
{
public static double CelsiusToFahrenheit(string temperatureCelsius)
{
// Convert argument to double for calculations.
double celsius = Double.Parse(temperatureCelsius);
// Convert Celsius to Fahrenheit.
double fahrenheit = (celsius * 9 / 5) + 32;
return fahrenheit;
}
public static double FahrenheitToCelsius(string temperatureFahrenheit)
{
// Convert argument to double for calculations.
double fahrenheit = Double.Parse(temperatureFahrenheit);
// Convert Fahrenheit to Celsius.
double celsius = (fahrenheit - 32) * 5 / 9;
return celsius;
}
}
class TestTemperatureConverter
{
static void Main()
{
Console.WriteLine("Please select the convertor direction");
Console.WriteLine("1. From Celsius to Fahrenheit.");
Console.WriteLine("2. From Fahrenheit to Celsius.");
Console.Write(":");
string selection = Console.ReadLine();
double F, C = 0;
switch (selection)
{
case "1":
Console.Write("Please enter the Celsius temperature: ");
F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine());
Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
break;
case "2":
Console.Write("Please enter the Fahrenheit temperature: ");
C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());
Console.WriteLine("Temperature in Celsius: {0:F2}", C);
break;
default:
Console.WriteLine("Please select a convertor.");
break;
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
輸出:
Please select the convertor direction 1. From Celsius to Fahrenheit. 2. From Fahrenheit to Celsius. :2 Please enter the Fahrenheit temperature: 20 Temperature in Celsius: -6.67 Press any key to exit.
靜態(tài)成員
非靜態(tài)類(lèi)可以包含靜態(tài)的方法、字段、屬性或事件。即使沒(méi)有創(chuàng)建類(lèi)的實(shí)例,也可以調(diào)用該類(lèi)中的靜態(tài)成員。始終通過(guò)類(lèi)名而不是實(shí)例名稱(chēng)訪問(wèn)靜態(tài)成員。無(wú)論對(duì)一個(gè)類(lèi)創(chuàng)建多少個(gè)實(shí)例,它的靜態(tài)成員都只有一個(gè)副本。靜態(tài)方法和屬性不能訪問(wèn)其包含類(lèi)型中的非靜態(tài)字段和事件,并且不能訪問(wèn)任何對(duì)象的實(shí)例變量(除非在方法參數(shù)中顯式傳遞)。
更常見(jiàn)的做法是聲明具有一些靜態(tài)成員的非靜態(tài)類(lèi),而不是將整個(gè)類(lèi)聲明為靜態(tài)類(lèi)。靜態(tài)字段有兩個(gè)常見(jiàn)的用法:一是記錄已實(shí)例化對(duì)象的個(gè)數(shù),二是存儲(chǔ)必須在所有實(shí)例之間共享的值。
靜態(tài)方法可以被重載但不能被重寫(xiě),因?yàn)樗鼈儗儆陬?lèi),不屬于類(lèi)的任何實(shí)例。
雖然字段不能聲明為 static const,但 const 字段的行為在本質(zhì)上是靜態(tài)的。這樣的字段屬于類(lèi)型,不屬于類(lèi)型的實(shí)例。因此,可以同對(duì)待靜態(tài)字段一樣使用 ClassName.MemberName 表示法來(lái)訪問(wèn) const 字段。不需要對(duì)象實(shí)例。
C# 不支持靜態(tài)局部變量(在方法范圍內(nèi)聲明的變量)。
通過(guò)在成員的返回類(lèi)型之前使用 static 關(guān)鍵字可以聲明靜態(tài)類(lèi)成員,如下面的示例所示:
public class Automobile
{
public static int NumberOfWheels = 4;
public static int SizeOfGasTank
{
get
{
return 15;
}
}
public static void Drive() { }
public static event EventType RunOutOfGas;
// Other non-static fields and properties...
}
靜態(tài)成員在第一次被訪問(wèn)之前并且在調(diào)用靜態(tài)構(gòu)造函數(shù)(如有存在)之前進(jìn)行初始化。若要訪問(wèn)靜態(tài)類(lèi)成員,應(yīng)使用類(lèi)名而不是變量名來(lái)指定該成員的位置,如下面的示例所示:
Automobile.Drive(); int i = Automobile.NumberOfWheels;
如果類(lèi)包含靜態(tài)字段,請(qǐng)?zhí)峁┰诩虞d類(lèi)時(shí)初始化這些字段的靜態(tài)構(gòu)造函數(shù)。
對(duì)靜態(tài)方法的調(diào)用以 Microsoft 中間語(yǔ)言 (MSIL) 生成調(diào)用指令,而對(duì)實(shí)例方法的調(diào)用生成 callvirt 指令,該指令還檢查 null 對(duì)象引用。但是,兩者之間的性能差異在大多數(shù)時(shí)候并不明顯。
C#的密封類(lèi)
使用 sealed 關(guān)鍵字可以防止繼承以前標(biāo)記為 virtual 的類(lèi)或某些類(lèi)成員。
通過(guò)在類(lèi)定義前面放置關(guān)鍵字 sealed,可以將類(lèi)聲明為密封類(lèi)。例如:
public sealed class D
{
// Class members here.
}
密封類(lèi)不能用作基類(lèi)。因此,它也不能是抽象類(lèi)。密封類(lèi)禁止派生。由于密封類(lèi)從不用作基類(lèi),所以有些運(yùn)行時(shí)優(yōu)化可以略微提高密封類(lèi)成員的調(diào)用速度。
在對(duì)基類(lèi)的虛成員進(jìn)行重寫(xiě)的派生類(lèi)上,方法、索引器、屬性或事件可以將該成員聲明為密封成員。在用于以后的派生類(lèi)時(shí),這將取消成員的虛效果。方法是在類(lèi)成員聲明中將 sealed 關(guān)鍵字置于 override 關(guān)鍵字的前面。例如:
public class D : C
{
public sealed override void DoWork() { }
}
上一篇:結(jié)合Visual C#開(kāi)發(fā)環(huán)境講解C#中事件的訂閱和取消訂閱
欄 目:C#教程
本文標(biāo)題:理解C#編程中的靜態(tài)類(lèi)和靜態(tài)成員以及密封類(lèi)
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6740.html
您可能感興趣的文章
- 01-10C#編程實(shí)現(xiàn)自定義熱鍵的方法
- 01-10C#編程獲取資源文件中圖片的方法
- 01-10C#中查找Dictionary中的重復(fù)值的方法
- 01-10C#將圖片存放到SQL SERVER數(shù)據(jù)庫(kù)中的方法
- 01-10關(guān)于nancy中的身份驗(yàn)證
- 01-10C#中的事務(wù)用法實(shí)例分析
- 01-10C#編程自學(xué)之?dāng)?shù)據(jù)類(lèi)型和變量二
- 01-10C#編程自學(xué)之開(kāi)篇介紹
- 01-10C#編程自學(xué)之?dāng)?shù)據(jù)類(lèi)型和變量三
- 01-10C#編程自學(xué)之運(yùn)算符和表達(dá)式


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改


