c# 類 class
當你定義一個類時,你定義了一個數據類型的藍圖。這實際上并沒有定義任何的數據,但它定義了類的名稱意味著什么,也就是說,類的對象由什么組成及在這個對象上可執行什么操作。對象是類的范例。構成類的方法和變量稱為類的成員。
1. 類的定義
類的定義是以關鍵字 class 開始,后跟類的名稱。類的主體,包含在一對花括號內。下面是類定義的一般形式:
<access specifier> class ?class_name { ? ? // member variables ? ? <access specifier> <data type> variable1; ? ? <access specifier> <data type> variable2; ? ? ... ? ? <access specifier> <data type> variablen; ? ? // member methods ? ? <access specifier> <return type> method1(parameter_list) ? ? { ? ? ? ? // method body ? ? } ? ? <access specifier> <return type> method2(parameter_list) ? ? { ? ? ? ? // method body ? ? } ? ? ... ? ? <access specifier> <return type> methodn(parameter_list) ? ? { ? ? ? ? // method body ? ? } }
請注意:
- 訪問標識符 <access specifier> 指定了對類及其成員的訪問規則。如果沒有指定,則使用默認的訪問標識符。類的默認訪問標識符是 internal,成員的默認訪問標識符是 private。
- 數據類型 <data type> 指定了變量的類型,返回類型 <return type> 指定了返回的方法返回的數據類型。
- 如果要訪問類的成員,你要使用點(.)運算符。
- 點運算符鏈接了對象的名稱和成員的名稱。
下面的范例說明了目前為止所討論的概念:
using system; namespace boxapplication { ? ? class box ? ? { ? ? ? ?public double length; ? // 長度 ? ? ? ?public double breadth; ?// 寬度 ? ? ? ?public double height; ? // 高度 ? ? } ? ? class boxtester ? ? { ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? box box1 = new box(); ? ? ? ?// 聲明 box1,類型為 box ? ? ? ? ? ? box box2 = new box(); ? ? ? ?// 聲明 box2,類型為 box ? ? ? ? ? ? double volume = 0.0; ? ? ? ? // 體積 ? ? ? ? ? ? // box1 詳述 ? ? ? ? ? ? box1.height = 5.0; ? ? ? ? ? ? box1.length = 6.0; ? ? ? ? ? ? box1.breadth = 7.0; ? ? ? ? ? ? // box2 詳述 ? ? ? ? ? ? box2.height = 10.0; ? ? ? ? ? ? box2.length = 12.0; ? ? ? ? ? ? box2.breadth = 13.0; ? ? ? ? ? ? ? ? ? ? ? ? // box1 的體積 ? ? ? ? ? ? volume = box1.height * box1.length * box1.breadth; ? ? ? ? ? ? console.writeline("box1 的體積: {0}", ?volume); ? ? ? ? ? ? // box2 的體積 ? ? ? ? ? ? volume = box2.height * box2.length * box2.breadth; ? ? ? ? ? ? console.writeline("box2 的體積: {0}", volume); ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
box1 的體積: 210 box2 的體積: 1560
2. 成員函數和封裝
類的成員函數是一個在類定義中有它的定義或原型的函數,就像其他變量一樣。作為類的一個成員,它能在類的任何對象上操作,且能訪問該對象的類的所有成員。
成員變量是對象的屬性(從設計角度),且它們保持私有來實現封裝。這些變量只能使用公共成員函數來訪問。
讓我們使用上面的概念來設置和獲取一個類中不同的類成員的值:
using system; namespace boxapplication { ? ? class box ? ? { ? ? ? ?private double length; ? // 長度 ? ? ? ?private double breadth; ?// 寬度 ? ? ? ?private double height; ? // 高度 ? ? ? ?public void setlength( double len ) ? ? ? ?{ ? ? ? ? ? ? length = len; ? ? ? ?} ? ? ? ?public void setbreadth( double bre ) ? ? ? ?{ ? ? ? ? ? ? breadth = bre; ? ? ? ?} ? ? ? ?public void setheight( double hei ) ? ? ? ?{ ? ? ? ? ? ? height = hei; ? ? ? ?} ? ? ? ?public double getvolume() ? ? ? ?{ ? ? ? ? ? ?return length * breadth * height; ? ? ? ?} ? ? } ? ? class boxtester ? ? { ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? box box1 = new box(); ? ? ? ?// 聲明 box1,類型為 box ? ? ? ? ? ? box box2 = new box(); ? ? ? ? ? ? ? ?// 聲明 box2,類型為 box ? ? ? ? ? ? double volume;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 體積 ? ? ? ? ? ? // box1 詳述 ? ? ? ? ? ? box1.setlength(6.0); ? ? ? ? ? ? box1.setbreadth(7.0); ? ? ? ? ? ? box1.setheight(5.0); ? ? ? ? ? ? // box2 詳述 ? ? ? ? ? ? box2.setlength(12.0); ? ? ? ? ? ? box2.setbreadth(13.0); ? ? ? ? ? ? box2.setheight(10.0); ? ? ? ? ? ? ? ? ? ? // box1 的體積 ? ? ? ? ? ? volume = box1.getvolume(); ? ? ? ? ? ? console.writeline("box1 的體積: {0}" ,volume); ? ? ? ? ? ? // box2 的體積 ? ? ? ? ? ? volume = box2.getvolume(); ? ? ? ? ? ? console.writeline("box2 的體積: {0}", volume); ? ? ? ? ? ? ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
box1 的體積: 210 box2 的體積: 1560
3. c# 中的構造函數
類的 構造函數 是類的一個特殊的成員函數,當創建類的新對象時執行。
構造函數的名稱與類的名稱完全相同,它沒有任何返回類型。
下面的范例說明了構造函數的概念:
using system; namespace lineapplication { ? ?class line ? ?{ ? ? ? private double length; ? // 線條的長度 ? ? ? public line() ? ? ? { ? ? ? ? ?console.writeline("對象已創建"); ? ? ? } ? ? ? public void setlength( double len ) ? ? ? { ? ? ? ? ?length = len; ? ? ? } ? ? ? public double getlength() ? ? ? { ? ? ? ? ?return length; ? ? ? } ? ? ? static void main(string[] args) ? ? ? { ? ? ? ? ?line line = new line(); ? ? ? ? ? ? ?// 設置線條長度 ? ? ? ? ?line.setlength(6.0); ? ? ? ? ?console.writeline("線條的長度: {0}", line.getlength()); ? ? ? ? ?console.readkey(); ? ? ? } ? ?} }
當上面的代碼被編譯和執行時,它會產生下列結果:
對象已創建 線條的長度: 6
默認的構造函數沒有任何參數。但是如果你需要一個帶有參數的構造函數可以有參數,這種構造函數叫做參數化構造函數。這種技術可以幫助你在創建對象的同時給對象賦初始值,具體請看下面范例:
using system; namespace lineapplication { ? ?class line ? ?{ ? ? ? private double length; ? // 線條的長度 ? ? ? public line(double len) ?// 參數化構造函數 ? ? ? { ? ? ? ? ?console.writeline("對象已創建,length = {0}", len); ? ? ? ? ?length = len; ? ? ? } ? ? ? public void setlength( double len ) ? ? ? { ? ? ? ? ?length = len; ? ? ? } ? ? ? public double getlength() ? ? ? { ? ? ? ? ?return length; ? ? ? } ? ? ? static void main(string[] args) ? ? ? { ? ? ? ? ?line line = new line(10.0); ? ? ? ? ?console.writeline("線條的長度: {0}", line.getlength()); ? ? ? ? ?// 設置線條長度 ? ? ? ? ?line.setlength(6.0); ? ? ? ? ?console.writeline("線條的長度: {0}", line.getlength()); ? ? ? ? ?console.readkey(); ? ? ? } ? ?} }
當上面的代碼被編譯和執行時,它會產生下列結果:
對象已創建,length = 10 線條的長度: 10 線條的長度: 6
4. c# 中的析構函數
類的 析構函數 是類的一個特殊的成員函數,當類的對象超出范圍時執行。
析構函數的名稱是在類的名稱前加上一個波浪形(~)作為前綴,它不返回值,也不帶任何參數。
析構函數用于在結束程序(比如關閉文件、釋放內存等)之前釋放資源。析構函數不能繼承或重載。
下面的范例說明了析構函數的概念:
using system; namespace lineapplication { ? ?class line ? ?{ ? ? ? private double length; ? // 線條的長度 ? ? ? public line() ?// 構造函數 ? ? ? { ? ? ? ? ?console.writeline("對象已創建"); ? ? ? } ? ? ? ~line() //析構函數 ? ? ? { ? ? ? ? ?console.writeline("對象已刪除"); ? ? ? } ? ? ? public void setlength( double len ) ? ? ? { ? ? ? ? ?length = len; ? ? ? } ? ? ? public double getlength() ? ? ? { ? ? ? ? ?return length; ? ? ? } ? ? ? static void main(string[] args) ? ? ? { ? ? ? ? ?line line = new line(); ? ? ? ? ?// 設置線條長度 ? ? ? ? ?line.setlength(6.0); ? ? ? ? ?console.writeline("線條的長度: {0}", line.getlength()); ? ? ? ? ? ? ? ? } ? ?} }
當上面的代碼被編譯和執行時,它會產生下列結果:
對象已創建 線條的長度: 6 對象已刪除
5. c# 類的靜態成員
我們可以使用 static 關鍵字把類成員定義為靜態的。當我們聲明一個類成員為靜態時,意味著無論有多少個類的對象被創建,只會有一個該靜態成員的副本。
關鍵字 static 意味著類中只有一個該成員的范例。靜態變量用于定義常量,因為它們的值可以通過直接調用類而不需要創建類的范例來獲取。靜態變量可在成員函數或類的定義外部進行初始化。你也可以在類的定義內部初始化靜態變量。
下面的范例演示了靜態變量的用法:
using system; namespace staticvarapplication { ? ? class staticvar ? ? { ? ? ? ?public static int num; ? ? ? ? public void count() ? ? ? ? { ? ? ? ? ? ? num++; ? ? ? ? } ? ? ? ? public int getnum() ? ? ? ? { ? ? ? ? ? ? return num; ? ? ? ? } ? ? } ? ? class statictester ? ? { ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? staticvar s1 = new staticvar(); ? ? ? ? ? ? staticvar s2 = new staticvar(); ? ? ? ? ? ? s1.count(); ? ? ? ? ? ? s1.count(); ? ? ? ? ? ? s1.count(); ? ? ? ? ? ? s2.count(); ? ? ? ? ? ? s2.count(); ? ? ? ? ? ? s2.count(); ? ? ? ? ? ? ? ? ? ? console.writeline("s1 的變量 num: {0}", s1.getnum()); ? ? ? ? ? ? console.writeline("s2 的變量 num: {0}", s2.getnum()); ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
s1 的變量 num: 6 s2 的變量 num: 6
你也可以把一個成員函數聲明為 static。這樣的函數只能訪問靜態變量。靜態函數在對象被創建之前就已經存在。下面的范例演示了靜態函數的用法:
using system; namespace staticvarapplication { ? ? class staticvar ? ? { ? ? ? ?public static int num; ? ? ? ? public void count() ? ? ? ? { ? ? ? ? ? ? num++; ? ? ? ? } ? ? ? ? public static int getnum() ? ? ? ? { ? ? ? ? ? ? return num; ? ? ? ? } ? ? } ? ? class statictester ? ? { ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? staticvar s = new staticvar(); ? ? ? ? ? ? s.count(); ? ? ? ? ? ? s.count(); ? ? ? ? ? ? s.count(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? console.writeline("變量 num: {0}", staticvar.getnum()); ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
變量 num: 3