類
從定議上講,類是一种數據結構,這种數據結構可能包含數據成員,函數成員以及其它的嵌套
類型.其中數據成員類型有常量,域和事件;函數成員類型有方法,屬性,索引指示器,操作符,
構造函數,和析構函數.
類的聲明
格式如下:
attributes class-modifiers CLASS identifier class-base class-body;
其中attributes,class-modifiers,class-base,class-body為可選項,Attributes為屬性集
,class-modifiers為類的修飾符,關鍵詞class後跟隨類的名稱,identifier,class-base和
class-body表示繼承方式和基類名.
類的修飾符
類的修飾符可以是以下幾种之一或者是它們的組合(在類的聲明中同一修飾符不允許出現多
次):
new--僅允許在嵌套類聲明時使用,表明類中隱藏了由基類中繼承而來的,與基類中同名的成
員.
public--表示不限制對該類的訪問.
protected--表示只能從所在類和所在類派生的子類進行訪問.
internal--只有其所在類才能訪問.
private--只有對包.Net中的應用程序或庫才能訪問.
abstract--抽像類,不允許建立類的實例.
sealed--密封類,不允許被繼承.
C#中的類只支持單繼承
類的成員
類的成員可以分為兩大類:類本身所聲明的,以及從基類中繼承而來的.
類的成員有以下類型:
成員常量,代表與類相關聯的常量值.
域,即類中的變量.
成員方法,復雜執行類中的計算和其它操作.
屬性,用於定議類中的值,並對它們進行讀寫.
事件,用於說明發生了什麼事情.
索引指示器,允許像使用數組那樣為類添加路徑列表.
操作符,定議類中特有的操作.
構造函數和析構函數,分別用於對類的實例進行初始化和銷毀.
包含有可執行代碼的成員被認為是類中的函數成員,這些函數成員有方法,屬性,索引指示器
,操作符,構造函數和析構函數.
類的成員修飾符
公有成員--C#中的公有成員提供了類的外部界面,允許類的使用者從外部進行訪問.公有成
員的修飾符為public,這是限制最少的一种訪問方式.
私有成員--C#中的私有成員僅限於類中的成員可以訪問,從類的外部訪問私有成員是不合法
的,如果在聲明中沒有出現成員的訪問修飾符,按照默認方式成員為私有的.私有成員的修飾
符為private.
保護成員--為了方便派生類的訪問,又希望成員對於外界是隱藏的,這時可以使用protected
修飾符,聲明成員為保護成員.
內部成員--使用internal修飾符的類的成員是一种特殊的成員.這种成員對於同一包中的應
用程序或庫是透明的,而在包.Net之外是禁止訪問的.
下面的例子說明一下類的成員的訪問修飾符的用法.
using system;
class vehicle //定議汽車類
{
public int wheels;//公有成員:輪子個數
protected float weight;//保護成員:重量
public void F()
{
wheels=4;//正確,允許訪問自身成員
weight=10;//正確,允許訪問自身成員
}
};
class train //定議火車類
{
public int num;//公有成員,車廂數目
private int passengers;//私有成員,乘客數
private float weight;//私有成員,重量
public void F()
{
num=5;//正確,允許訪問自身成員
weight=100;//正確,允許訪問自身成員
Vehicle v1=new Vehicle();
v1.wheels=4;//正確,允許訪問v1的公有成員
//v1.weight=6;錯誤,不允許訪問v1的保護成員
weight=6;
}
}
class Car:Vehicle //定議轎車類,繼承自汽車類
{
int passengers;//私有成員:乘客數
public void F()
{
Vehicle v1=new Vehicle();
v1.wheels=4; //正確,允許訪問v1的公有成員
v1.weight=6;//正确,允許訪問v1的保護成員
}
}
this保留字
保留字this僅限於在構造函數,類的方法和類的實例中使用,它有以下含議:
在類的構造函數中出現的this作為一個值類型,它表示對正在構造的對像本身的引用.
在類的方法中出現的this作為一個值類型,它表示對調用該方法的對像的引用.
在結構的構造函數中出現的this作為一個變量類型,它表示對正在構造的結構的引用.
在結構的方法中出現的this作為一個變量類型,它表對調用該方法的結構的引用.
除此以外,在其它地方使用this保留字都是不合法的.
下面的代碼演示了如何使用this保留字.
using system;
class A
{
public int x;
public void Main()
{
x=5;
Console.WriteLine("The value of x is:{0}",x);
Console.WriteLine("The value of this x is:{0}",this.x);
}
}
程序運行的結果應該是:
The value of x is:5
The value of this x is:5
下面再舉一個例子說明this的用法
using system;
class face
{
int x;
public int GetFace()
{
float temp;
int save=x;
int a=1;
while (x>a)
{
a++;
temp=this.x/a;
x/=a;
if ((float)x!=temp)
{
return -1;
}
}
swap(this.x,save);
return save;
}
}
靜態成員和非靜態成員
類中的成員要麼是靜態的,要麼是非靜態的.一般來說,靜態成員是屬於類所有的,非靜態成
員是屬於類的實例----對像.
以下示例代碼演示了如何聲明靜態和非靜態成員
using system;
class test
{
int x;
static int y;
void f()
{
x=1; //正確.等價於this.x=1
y=1; //正確.等價於test.y=1
}
}
static void g()
{
x=1; //錯誤,不能訪問this.x
y=1; //正確,等價於test.y=1
}
static void main()
{
Test t=new Test();
t.x=1; //正確
t.y=1; //錯誤,不能在類的實例中訪問靜態成員
Test.x=1; //錯誤,不能按類訪問非靜態成員
Test.y=1; //正確
}
類的非靜態成員屬於類的實例所有,每創建一個類的實例,都在內存中為非靜態成員開辟了
一塊區域.而類的靜態成員屬於類所有,為這個類的所有實例所共享.無論這個類創建了多少
個副本,一個靜態成員在內存中只占有一塊區域.
成員常量
下面是一個成員常量的聲明的例子:
class a
{
public const double x=1.0;
public const double y=2.0;
public const double z=3.0;
}
關鍵字const用於聲明常量,後跟數據類型的聲明.類的常量可 加上以下修飾符:
new
public
protected
internal
private
構造函數和析構函數
構造函數用於執行類的實例的初始化.在訪問一個類的時候,系統將最先執行構造函數中的
語句.實際上,任何構造函數的執行都隱式地調用了系統提供默認的構造函數base().
使用構造函數請注意以下幾個問題:
一個類的構造函數通常與類名相同.
構造函數不聲明返回類型.
一般地,構造函數總是public類型的.如果是private類型的,表明類不能被實例化,這通常用
於只含有靜態成員的類.
在構造函數中不要做對類的實例進行初始化以外的事情,也不要嘗試顯式地調用構造函數.
下面的例子示範了構造函數的使用:
class a
{
int x=0,y=0,count;
public a()
{
count=0;
}
public a(int vx,int vy)
{
x=vx;
y=vy;
}
}
構造函數的參數
構造函數可以是不帶參數的,這樣對類的實例的初始化是固定的.有時,我們在對類進行實例
化時,需要傳遞一定的數據,來對其中的各种數據初始化,使得初始化不再是一成不變的,這
時,我們可以使用帶參數的構造函數,來實現對類的不同實例的不同初始化.
在帶有參數的構造函數中,類在實例化時必須傳遞參數,否則該構造函數不被執行.
下面是一個例子
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class Vehicle //定議汽車類
{
public int wheels;//公有成員;輪子個數
protected float weight; //保掮成員;重量
public Vehicle() { ;}
public Vehicle(int w, float g)
{
wheels = w;
weight = g;
}
public void Show()
{
Console.WriteLine("the wheel of vehicle is:{0}", wheels);
Console.WriteLine("the weight of vehicle is:{0}", weight);
}
}
class Train //定議火車類
{
public int num;
private int passengers;
private float weight;
public Train() { ;}
public Train(int n, int p, float w)
{
num = n;
passengers = p;
weight = w;
}
public void Show()
{
Console.WriteLine("the num of train is:{0}", num);
Console.WriteLine("the weight of train is:{0}", weight);
Console.WriteLine("thie Passengers train car is:{0}", passengers);
}
}
class Car : Vehicle//定議轎車類
{
int passengers;
public Car(int w, float g, int p)
: base(w, g)
{
wheels = w;
weight = g;
passengers = p;
}
new public void Show()
{
Console.WriteLine("the wheel of car is:{0}", wheels);
Console.WriteLine("the weight of car is:{0}", weight);
Console.WriteLine("thie passengers of car is:{0}", passengers);
}
}
class Test
{
public static void Main()
{
Vehicle v1 = new Vehicle(4, 5);
Train t1 = new Train();
Train t2 = new Train(10, 100, 100);
Car c1 = new Car(4, 2, 4);
v1.Show();
t1.Show();
t2.Show();
c1.Show();
}
}
}
程序運行結果如下:
the wheel of vehicle is:4
the weight of vehicle is:5
the num of train is:0
the weight of train is:0
thie Passengers train car is:0
the num of train is:10
the weight of train is:100
thie Passengers train car is:100
the wheel of car is:4
the weight of car is:2
thie passengers of car is:4
析構函數
在類的實例超出範圍時,我們希望確保它所占的存儲能被收回.C#中提供了析構函數,用於專門釋放被占用的系統資源.
析構函數的名字和類名相同,只是在前面加了一個符號"~".析構函數不接受任何參數,也不返回任何值.