- ASP.NET程序設計教程(第2版)
- 崔連和主編
- 3374字
- 2020-09-18 18:22:50
3.8 類和對象
3.8.1 類
在C#中,類是一種功能強大的數據類型,而且是面向對象的基礎。類定義屬性和行為,程序員可以聲明類的實例,從而可以利用這些屬性和行為。
類具有如下特點:
1)C#類只支持單繼承,也就是類只能從一個基類繼承實現。
2)一個類可以實現多個接口。
3)類定義可以在不同的源文件之間進行拆分。
4)靜態類是僅包含靜態方法的密封類。
類其實是創建對象的模板,類定義了每個對象可以包含的數據類型和方法,從而在對象中可以包含這些數據,并能夠實現定義的功能。
類的聲明的結構形式如下:

3.8.2 類的操作
1.定義類
類通常體現了現實中的某類事物,或者開發者要研究的對象。在C#中,幾乎所有的程序代碼都是在類中實現的。我們以現實生活中的“建筑物”為例,定義一個關于建筑物的類。考慮到建筑物的特點,建筑物應該包括名稱、樓層數、面積、居住人數等基本信息。可以定義一個叫作Building的類以代表建筑物。包含的信息對應如下。

則可以初步定義類Building。

定義類Building就相當于創建了一個新的數據類型。可以聲明對象了。

有了以上初始化操作,就可以計算人均面積等其他信息了。

同一個類定義的每個對象都包含一組類中定義的實際變量的副本。每個對象包含的內容可以和另一個對象完全不同(除了具有相同類型外)。它們之間也可以沒有任何聯系。

2.給Building類添加方法
類的方法通常對類中包含的數據執行某種操作,并提供對類中數據的訪問。
areaPP:計算人均面積改成類中的方法。可以封裝類中直接與建筑物相關的數量,從而增強該類的面向對象結構。

方法可以返回值,方法采用如下形式的return語句給調用程序返回一個值:

使用返回值改進AreaPerPerson()方法的實現。

也可以給Building類添加帶參數的方法。假設每個居住者必須有一定的最小空間,那么由此可以計算出建筑物的最大居住人數。將該新方法命名為MaxOccupant()。

3.構造函數

以上必須使用一系列語句手動設置每個Building對象的實例變量。
而在專業人員編寫的C#代碼中,很少使用這種方式。一種原因是這種方式容易出錯(有可能忘記設置某個字段的值),另一種原因是有一種更好的實現該任務的方式:構造函數。
構造函數用于在創建對象時初始化對象。它的名稱與類相同。語法上類似于方法。但是,構造函數沒有顯式的返回值類型。以下是Building類的構造函數。

初始化類時使用如下格式:

4.析構函數
可以定義在垃圾回收程序最終銷毀對象之前調用的方法,該方法稱為析構函數,它可以用于一些非常特殊的情況,確保對象徹底地終止。
析構函數格式:

例如:~Building()

總結上面對類的說明和實例,在C#中,類可以包含如下幾種成員:
1)字段,是被視為類的一部分的對象實例,通常用來保存類數據,一般為私有成員。
2)屬性,是類中可以像類中的字段一樣訪問的方法。屬性可以為類字段提供保護,避免字段在對象不知道的情況下被修改。
3)方法,定義類可以執行的操作。
4)事件,是向其他對象提供有關事件發生通知的一種方式,事件是使用委托來定義和觸發的。
5)構造函數,是第一次創建對象時調用的方法,用來對對象進行初始化。
6)析構函數,是對象使用完畢后從內存中清理對象占用的資源,在C#中一般不需要明確定義析構函數,CLR會幫助解決內存的釋放問題。
3.8.3 類的訪問控制
對于類中的成員的訪問,分為公有訪問和私有訪問兩種:公有訪問使用關鍵字:public,私有訪問使用關鍵字:private。說明如下。
1)public:使用public說明符修飾類的成員時,該成員可以由程序中的任意其他代碼訪問,包括其他類中定義的方法。
2)private:使用private說明符修飾類的成員時,該成員只可以由它所在類中的其他成員訪問。如果沒有用任何訪問說明符,類成員默認為private。
棧是面向對象編程的典型實例,因為它將信息的存儲和訪問這些信息的方法組合在一起。
棧存儲的成員是私有的,訪問方法是公有的,因此它是說明類的訪問控制的最佳選擇。
棧這種數據結構主要有以下這些基本操作。可以寫出它們的實現代碼如下。
(1)定義棧

(2)初始化棧(構造函數)

(3)進棧

(4)出棧

(5)判滿棧

(6)判空棧

(7)返回棧大小

(8)返回元素數量

將上述棧的基本操作所對應的代碼,放到定義棧的Class中,完成棧的完整定義。則可以在Main中調用“棧”這個類,實例化棧為一個對象,并進行各種棧的操作。
Main()調用的代碼如下:

3.8.4 繼承
1.繼承概念和定義方法
繼承是面向對象編程的一大特性,通過繼承,類可以從其他類繼承相關特性。被繼承的類稱為基類,而繼承基類的類稱為派生類。
派生類將獲取基類的所有非私有數據和行為,以及派生類為自己定義的其他數據和行為。
繼承的實現方式是:在聲明類時,在類名稱后放置一個冒號,然后在冒號后指定要從中繼承的類。例如,類B從類A中繼承,類A被稱為基類,類B被稱為派生類:

下面示例中的TwoDShape類存儲二維對象(如正方形、三角形、矩形等)的高度和寬度:


定義派生類:

主函數調用:

2.成員訪問和繼承
類成員經常聲明為私有的(private),以避免對它們執行未授權的訪問和破壞。繼承一個類不會破壞私有訪問的限制。
派生類雖然包括基類的所有成員,但它不能訪問基類中的私有成員。例如將TwoDShape類的Width和Height成員聲明為私有,則Triangle類將不能訪問它們。
私有類成員總保持對其所在類的私有性,它不能被類外部的任何代碼訪問,包括派生類。
訪問私有成員的解決辦法如下。
(1)使用protected成員
protected保護成員在類層次結構中是共有的,但在該層次之外是私有的。
(2)使用公有屬性
改寫基類TwoDShape添加屬性:

3.構造函數和繼承
基類和派生類都可以有自己的構造函數。問題是,到底哪個構造函數構件派生類的對象?答案是,基類的構造函數構造對象的基類部分,而派生類的構造函數構造對象的派生類部分。
4.虛方法和重寫
虛方法是指在基類中聲明為virtual并在一個或多個派生類中使用override重新定義的方法。重寫體現了類的多態性。
3.8.5 Object類(System.Object)
C#定義了一個特殊的類Object,它是其他所有的類和類型的隱式基類。也就是說,所有其他類型都是從Object類派生的。這意味著Object類型的引用變量可以指向任何其他類型的對象。典型的應用為裝箱和拆箱。下面為示例代碼:

再舉一個例子:創建一個Object數組,并給其中的元素賦予不同類型的值。

3.8.6 對象
世界是由許多不同種類的對象構成的,每一個對象都有自己的運動規律和狀態。面向對象程序設計是用機器語言模擬客觀世界的方法,與面向過程相比,所有的對象被賦予屬性和方法,使編程更富有人性化。對于如何區分類、對象、屬性和方法,下面用生活中的實物來舉例說明。
高速上正在行駛的一輛紅色的豐田轎車,乘車人數五人,可以用于基本交通使用,由于超速行駛,交警當場開了罰單,并登記了車牌號碼、違規類型、開單日期和車主信息。如表3-26所示。
表3-26 對象的概念

1.類(Class)
類是對具有相同特征的一類事物所做的歸納。類的概念來源于人們認識自然、認識社會的過程,現實世界中的類是錯綜復雜、種類繁多的,聰明的人類學會了將復雜的事物進行分類。例如,由大小各異的汽車抽象出車的概念,由各式各樣的鳥兒抽象出鳥類的概念等。
2.對象(Object)
一切皆為對象。客觀世界由各種各樣的實體組成,這些實體就稱為對象,可以指具體事物也可以指抽象的事物,它是由數據加動作組成。對象是類的實例化,是實實在在存在的。例如,一只黃鸝鳥、一座房子,都是對象。對象是對具有某些特性的具體事物的抽象,對象之間的相互作用是通過發送消息進行的。
3.屬性(Property)
屬性就是對象狀態的描述,每個對象具有各自的屬性。例如,小貓的體重是1.5kg,椅子的顏色是紅色,沙發的價格是2000元,這些都是它們的屬性,體現了個體對象的性質。
4.方法(Method)
方法反映了對象本身可以完成的動作。例如一個學生,他會聽課、做筆記、打籃球等,總結為一句話:方法就是行為。
5.事件(Event)
事件是指對象本身對外部變化所做出的響應。在表3-26中,可以看出,交警令司機停車,這就是一個外部變化,而對象做出的反應是停車,也就是說,停車的動作就是一個事件。
對象是類的實例化,只有對象才能包含數據、執行行為和觸發事件,而類只不過就像int一樣是數據類型,只有實例化才能真正發揮作用。
對象具有以下特點:
1)C#中使用的全都是對象。
2)對象是實例化的,對象是從類和結構所定義的模板中創建的。
3)對象使用屬性獲取和更改它們所包含的信息。
4)對象通常具有允許它們執行操作的方法和事件。
5)所有C#對象都繼承自Object。
6)對象具有多態性,對象可以實現派生類和基類的數據和行為。
對象的聲明就是類的實例化,傳遞回該對象的引用。此引用引用了新對象,但不包含對象數據本身。
類實例化的方式很簡單,通過使用new來實現。例如:
