C# 類別(Class)
當您定義一個類別時,您定義了一個資料類型的藍圖。這實際上並沒有定義任何的數據,但它定義了類別的名稱意味著什麼,也就是說,類別的物件由什麼組成及在這個物件上可執行什麼操作。物件是類別的實例。構成類別的方法和變數成為類別的成員。
類別的定義
類別的定義是以關鍵字 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
成員函數和封裝
類別的成員函數是一個在類別定義中有它的定義或原型的函數,就像其他變數一樣。作為類別的一個成員,它能在類別的任何物件上操作,並且能存取該物件的類別的所有成員。
成員變數是物件的屬性(從設計角度),並且它們保持私有來實現封裝。這些變數只能使用公共成員函數來存取。
讓我們使用上面的概念來設定和取得一個類別中不同的類別成員的值:
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
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
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 对象已删除
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