實驗三類與類的封裝_第1頁
實驗三類與類的封裝_第2頁
實驗三類與類的封裝_第3頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、實驗三類與類的封裝【實驗?zāi)康呐c要求】理解面向?qū)ο蟪绦蛟O(shè)計的思想和基本概念使用構(gòu)造函數(shù)和析構(gòu)函數(shù)給類寫方法給一個類增加屬性理解靜態(tài)方法和實例方法之間的異同掌握方法的重載掌握類索引器的編寫方式掌握運算符的重載【實驗內(nèi)容與步驟】類是C#語言實現(xiàn)面向?qū)ο蟪绦蛟O(shè)計的基礎(chǔ),它是C#封裝的基本單元,類把對 象、屬性和方法這些類成員封裝在一起構(gòu)成一個有機的整體,即數(shù)據(jù)機構(gòu)。在 C#中,類是程序的最核心部分,沒有了類,就連簡單的C#程序都不能編譯。類是可以包含數(shù)據(jù)成員(常數(shù)和字段)、函數(shù)成員(方法、屬性、事件、 索引器、運算符、實例構(gòu)造函數(shù)、靜態(tài)構(gòu)造函數(shù)和析構(gòu)函數(shù))以及嵌套類型的數(shù) 據(jù)結(jié)構(gòu)。類類型支持繼承,繼承

2、是派生類可用以擴展和專用化基類的機制。一、類的聲明類的聲明就是定義一個新類,其格式如下:屬性類修飾符class 標識符:基類類體;類聲明包含一組可選的屬性(C#使程序員可以創(chuàng)造新的說明性信息種 類,稱為屬性),后跟一組可選的類修飾符(n ew;public;protected;i nternal;private;abstract;sealed ),然后是關(guān)鍵字class和一個命名該類的標識符,接著是一個可選的繼承基類,最后是可根 據(jù)需要后接一個分號的類體。類的成員類的成員包括由它的類成員聲明引入的成員和從直接基類繼承的成員 類的成員分為下列幾種類別: 常數(shù),表示與類相關(guān)聯(lián)的常數(shù)值。 字段,類的

3、變量。方法,實現(xiàn)可由類執(zhí)行的計算和操作。 屬性,定義與讀取和寫入這些特性相關(guān)的命名特性。 事件,定義可由類生成的通知。索引器,允許以與索引數(shù)組相同的方式索引類的實例。 運算符,定義可以應(yīng)用于類的實例的表達式運算符。 實例構(gòu)造函數(shù),實現(xiàn)初始化類的實例所需要的操作。 析構(gòu)函數(shù),實現(xiàn)在永久性放棄類的實例之前要執(zhí)行的操作。 靜態(tài)構(gòu)造函數(shù),實現(xiàn)初始化類自身所需要的操作。 類型,表示類的局部類型??梢园蓤?zhí)行代碼的成員被總稱為類的函數(shù)成員。類的函數(shù)成員是該類的方 法、屬性、事件、索引器、運算符、實例構(gòu)造函數(shù)、析構(gòu)函數(shù)和靜態(tài)構(gòu)造函數(shù)。類聲明創(chuàng)建新的聲明空間, 而由類聲明包含的最近的類成員聲明將新成員引入到

4、 此聲明空間中。下列規(guī)則適用于類成員聲明:實例構(gòu)造函數(shù)、靜態(tài)構(gòu)造函數(shù)和析構(gòu)函數(shù)必須具有與最近的封閉類相同的名稱。 所有其他成員必須具有與最近封閉類不同的名稱。常數(shù)、字段、屬性、事件或類型的名稱必須不同于在同一個類中聲明的所有其他 成員的名稱。方法的名稱必須不同于在同一個類中聲明的所有其他非方法的名稱。 此外,方法 的簽名必須不同于在同一個類中聲明的所有其他方法的簽名。實例構(gòu)造函數(shù)的簽名必須不同于在同一個類中聲明的所有其他實例構(gòu)造函數(shù)的 簽名。索引器的簽名必須不同于在同一個類中聲明的所有其他索引器的簽名。 運算符的簽名必須不同于在同一個類中聲明的所有其他運算符的簽名。 類的繼承成員不是類的聲明空

5、間的組成部分。 因此,允許派生類用與繼承成員相 同的名稱或簽名來聲明成員(這實質(zhì)上隱藏了繼承成員)。三、構(gòu)造函數(shù)與析構(gòu)函數(shù) 在可以訪問一個類的方法、屬性或任何其它東西之前, 第一條執(zhí)行的語句是包 含有相應(yīng)類的構(gòu)造函數(shù)。 甚至你自己不寫一個構(gòu)造函數(shù), 也會有一個缺省的構(gòu)造 函數(shù)提供給你。class TestClasspublic TestClass(): base() /由編譯器提供一個構(gòu)造函數(shù)總是和它的類名相同,但是,它沒有聲明返回類型??傊瑯?gòu)造函 數(shù)總是 public 的,你可以用它們來初始化變量。public TestClass()/ 在這給變量/ 初始化代碼等等。如果類僅包含靜態(tài)成員

6、(能以類型調(diào)用, 而不是以實例調(diào)用的成員 ) ,你可以創(chuàng)建 一個 private 的構(gòu)造函數(shù)。private TestClass() 盡管存取修飾符在這一章的后面將要大篇幅地討論, 但是 private 意味著從類的 外面不可能訪問該構(gòu)造函數(shù)。 所以, 它不能被調(diào)用, 且沒有對象可以自該類定義 被實例化。并不僅限于無參數(shù)構(gòu)造函數(shù)你可以傳遞初始參數(shù)來初始化成員。public TestClass(string strName, int nAge) . 作為一個C/C+程序員,你可能習(xí)慣于給初始化寫一個附加的方法,因為在構(gòu)造 函數(shù)中沒有返回值。當然,盡管在 C#中也沒有返回值,但你可以引發(fā)一個自制

7、的異常,以從構(gòu)造函數(shù)獲得返回值。但是,當你保留引用給寶貴的資源, 應(yīng)該想到寫一個方法來解決: 一個可以被顯 式地調(diào)用來釋放這些資源。 問題是當你可以在析構(gòu)函數(shù) (以類名的前面加 的方 式命名)中做同樣的事情時,為何還要寫一個附加的方法 .TestClass()/ 清除你應(yīng)該寫一個附加方法的原因是垃圾收集器, 它在變量超出范圍后并不會立即被 調(diào)用,而僅當間歇期間或內(nèi)存條件滿足時才被觸發(fā)。 當你鎖住資源的時間長于你 所計劃的時間時,它就會發(fā)生。因此,提供一個顯式的釋放方式是一個好主意,它同樣能從析構(gòu)函數(shù)中調(diào)用public void Release()/ 釋放所有寶貴的資源TestClass()Re

8、lease();調(diào)用析構(gòu)函數(shù)中的釋放方法并不是必要的總之,垃圾收集會留意釋放對象 但沒有忘記清除是一種良好的習(xí)慣。四、類方法既然對象能正確地初始化和結(jié)束,所剩下來的就是往類中增加功能。在 大多數(shù)情況下,功能的主要部分在方法中能得到實現(xiàn)。 以往,對于每個程序來 說,所有的工作都在 Main() 方法中實現(xiàn)。這對于功能簡單的程序是合適的,因 為僅僅用來學(xué)習(xí)一些概念。有個更好的方法來組織你的程序,那就是使用方法。 方法是很有用的,因為方法可以讓你在不同的單元中分開設(shè)計你的邏輯模塊。方法的結(jié)構(gòu)格式如下: 屬性 修飾符 返回值類型 方法名(參數(shù)) 方法體return 表達式 4.1.1 值傳遞參數(shù) 我們

9、在前面的例子中見過的一個參數(shù)就是值傳遞參數(shù)。你用一個值傳遞 參數(shù)通過值傳遞一個變量給一個方 法方法的變量被調(diào)用者傳遞進來的值的一個拷貝初始化。清單 4.1 示范值 傳遞參數(shù)的使用。清單 4.1 通過值傳遞參數(shù)1: using System;2:3: public class SquareSample4: 5: public int CalcSquare(int nSideLength)6: 7: return nSideLength*nSideLength;8: 9: 10:11: class SquareApp12: 13: public static void Main()14: 15:

10、SquareSample sq = new SquareSample();16: Console.WriteLine(sq.CalcSquare(25).ToString(); 17: 18: 因為傳遞值而不是引用 (地址)給一個變量,所以當調(diào)用方法時 (見第 16 行) ,可以使用一個常量表達式 (25) 。4.1.2 引用參數(shù) 盡管可以利用值傳遞參數(shù)和返回值建立很多方法,但你一想到要傳遞值 并原地修改它 ( 也就是在相同的內(nèi)存位置 ) ,就沒有那么好操作了。 這里用引用參 數(shù)就很方便。void myMethod(ref int nInOut) 因為傳遞了一個變量給該方法 ( 不僅僅是它的值

11、 ) ,變量必須被初始化。 否則,編譯器會報警。清單 4.2 顯示如何用一個引用參數(shù)建立一個方法。清單 4.2 通過引用傳遞參數(shù)1: / class SquareSample2: using System;3:4: public class SquareSample5: 6: public void CalcSquare(ref int nOne4All)7: 8: nOne4All *= nOne4All;9: 10: 11:12: class SquareApp13: 14: public static void Main()15: 16: SquareSample sq = new Sq

12、uareSample();17:18: int nSquaredRef = 20; /一定要初始化19: sq.CalcSquare(ref nSquaredRef);20: Console.WriteLine(nSquaredRef.ToString();21: 22: 正如所看到的, 所有要做的就是給定義和調(diào)用都加上 ref 限定符。因為變量通過 引用傳遞,就可以用它來計算出結(jié)果并傳回該結(jié)果。 但是,在現(xiàn)實的應(yīng)用程序中, 強烈建議要用兩個變量,一個值傳遞參數(shù)和一個引用參數(shù)。4.1.3 輸出參數(shù)傳遞參數(shù)的第三種選擇就是把它設(shè)作一個輸出參數(shù)。 正如該名字所暗示, 一個輸出參數(shù)僅用于從方法傳遞回

13、一個結(jié)果。它和引用參數(shù)的另一個區(qū)別在于: 調(diào)用者不必先初始化變量才調(diào)用方法。這顯示在清單 4.3 中。清單 4.3 定義一個輸出參數(shù)1: using System;2:3: public class SquareSample4: 5: public void CalcSquare(int nSideLength, out int nSquared)6: 7: nSquared = nSideLength * nSideLength;8: 9: 10:11: class SquareApp12: 13: public static void Main()14: 15: SquareSample

14、sq = new SquareSample();16:17: int nSquared; /不必初始化18: sq.CalcSquare(15, out nSquared);19: Console.WriteLine(nSquared.ToString();20: 21: 4.1.4 數(shù)組參數(shù)的傳遞當方法的參數(shù)前帶有 params 關(guān)鍵字 , 這就是一個帶數(shù)組型參數(shù)的方法 在方法的參數(shù)列表中使用params關(guān)鍵字,可用于表示方法的形參個數(shù)不確定,這 樣就可以在使用方法的過程中改變傳入方法的實參個數(shù) .帶有關(guān)鍵字params的數(shù)組型參數(shù)必須是方法的參數(shù)列表中最后一個參 數(shù), 否則會出現(xiàn)編譯錯誤

15、.數(shù)組型參數(shù)中的數(shù)組必須是一維數(shù)組類型 , 如 int,string( 鋸齒 型數(shù)組 ), 但 int, 二維數(shù)組則不能用來作為數(shù)組參數(shù) .示例 3:using System; public class ParamTest 定義帶數(shù)組型參數(shù)的方法成員public void para(params int ary) /Console.Write(n 數(shù)組中包含 0 個元素: ,ary.Length);for (int t=0;tary.Length;t+)aryt+; / 改變形參數(shù)組元素的值Console.Write( “ t0 ” , a ryt); / 打印形參數(shù)組元素的值 public

16、static void Main()int m=1,n=2,p=3,q=4;ParamTest app=new ParamTest(); int testArr=new intm,n,5;);Console.WriteLine( 調(diào)用方法之前的數(shù)組元素值為: foreach(int t in testArr)Console.Write( “ t0 ”,t); / 打印形參數(shù)組元素的值app.para(testArr);/ 用數(shù)組名作為實參為: );Console.WriteLine(n 調(diào)用方法之后的數(shù)組元素值為: );foreach(int t in testArr)Console.Writ

17、e(t0,t); / 打印形參數(shù)組元素的值app.para(m,n,p,q);/有 4 個實參與形參類型對應(yīng)Console.WriteLine();五、靜態(tài)方法與實例方法在類中,與上述實例方法相對應(yīng)的是靜態(tài)方法, 在定義類的方法成員時帶上 Static 修飾符,就可以將方法定義為靜態(tài)方法。另外注意,定義一個靜態(tài)方法 時,不能含有 Virtual,abstract, 和 override 修飾符。靜態(tài)方法與靜態(tài)成員變 量類似,雖然在類中定義它, 但他不屬于某個具體的實例。 靜態(tài)方法只能訪問類 中的靜態(tài)成員,而實例方法可以訪問類中的所有成員。示例 1: public class studentst

18、atic int studcount=0;/ 定義一個私有的靜態(tài)變量成員,用 于統(tǒng)計學(xué)生人數(shù)public student() studcount+; / 統(tǒng)計學(xué)生人數(shù)public static int GetStudentCount()/ 定義一個靜態(tài)方法 return(studcount); / 靜態(tài)方法訪問靜態(tài)成員變量 class AppStudpublic static void Main()student student1=new student();/ 創(chuàng)建類的一個實 例Console.WriteLine( 學(xué)生人數(shù) =0,student.GetStudentCount();/ 通過

19、類名訪問靜態(tài)方法 student student2=new student();/ 創(chuàng)建類的另一個 實例Console.WriteLine( 學(xué)生人數(shù) =0,student.GetStudentCount();六、方法重載重載是面向?qū)ο蟪绦蛟O(shè)計的一個重要特征 , 通過重載可以使多個具有相同 功能但參數(shù)不同的方法共享同一個方法名 . 這樣將降低程序員的工作強度 .示例 2:Using System;Class printclasspublic void print (int i)/ 打印整數(shù)Console.WriteLine( “ 打印整數(shù) 0 ”,i);打印整數(shù)打印整數(shù) 0 ” ,i);打印字

20、符串打印字符串 0 ”,s);public void print (uint i)/Console.WriteLine(Public void print(string s) /Console.WriteLine(Public void print(params int arys) /打印 數(shù)組foreach(int a in arys)Console.Write( “0 t ”,a);Public static void Main()int myary=new int2,4,6,8,10;Printclass app=new printclass();App.print(int)6); /

21、調(diào)用打印整數(shù)方法App.print(uint)6);/ 調(diào)用打印無符號整數(shù)方法App.print( “方法重載好處多 ! ”);/ 調(diào)用打印字符 串方法App.print(myary); /調(diào)用打印數(shù)組方法七、類屬性屬性是提供對對象或類的特性的訪問的成員。屬性的示例包括字符串的長度、字體的大小、窗口的標題、客戶的名稱,等等。屬性是字段的自然擴展 兩者都是具有關(guān)聯(lián)類型的命名成員,而且訪問字段和屬性的語法是相同的。 然而,與字段不同,屬性不表示存儲位置。相反,屬性有訪問器,這些訪問器指 定要在它們的值被讀取或?qū)懭霑r執(zhí)行的語句。 因此屬性提供將操作與對象屬性的 讀取和寫入相關(guān)聯(lián)的機制;另外,它們還允

22、許對此類屬性進行計算。屬性聲明:class 類名 修飾符 數(shù)據(jù)類型 屬性名get ;set ;示例 4:。兩本示例展示一個 Person 類,它有兩個屬性: Name(string) 和 Age (int) 個屬性都是讀 / 寫屬性。/ person.csusing System;class Personprivate string myName =N/A; private int myAge = 0;/ Declare a Name property of type string:public string Namegetreturn myName;set myName = value;/

23、Declare an Age property of type int:public int Agegetreturn myAge;set myAge = value;public override string ToString()return Name = + Name + , Age = + Age;public static void Main()Console.WriteLine(Simple Properties);/ Create a new Person object:Person person = new Person();/ Print out the name and t

24、he age associated with the person: Console.WriteLine(Person details - 0, person);/ Set some values on the person object: person.Name = Joe;person.Age = 99; Console.WriteLine(Person details - 0, person);/ Increment the Age property: person.Age += 1;Console.WriteLine(Person details - 0, person); 輸出Sim

25、ple PropertiesPerson details - Name = N/A, Age = 0Person details - Name = Joe, Age = 99Person details - Name = Joe, Age = 100代碼討論請注意聲明屬性的方式,例如,考慮 Name 屬性:public string Name getreturn myName;setmyName = value;這使得獲取和設(shè)置屬性值屬性的“設(shè)置” (Set) 方法和“獲取” (Get) 方法包含在屬性聲明中。 可以通過控制是否包含“獲取”方法或“設(shè)置”方法來控制屬性是讀 / 寫屬性、只讀屬性

26、還是只寫屬性。聲明了屬性后, 可像使用類的字段那樣使用這些屬性。時都可以使用非常自然的語法,如以下語句中所示:person.Name = Joe;person.Age = 99;注意屬性“設(shè)置”方法中可以使用一個特殊的value 變量。該變量包含用戶指定的值,例如:myName = value;請注意用于使 Person 對象上的 Age 屬性遞增的簡潔語法:person.Age += 1;如果使用單獨的“設(shè)置”方法和“獲取”方法建立屬性模型,等效代碼 可能是:person.SetAge(person.GetAge() + 1);本示例中重寫了 ToString 方法:public overr

27、ide string ToString()return Name = + Name + , Age = + Age;注意程序中未顯式使用 ToString 。默認情況下,它由 WriteLine 調(diào)用來 調(diào)用。八、類索引索引器是使對象能夠用與數(shù)組相同的方式進行索引的成員索引器的工作方式類似于屬性。只是索引器用來訪問類中的數(shù)組型對象 元素,而屬性用來被用來訪問類中的私有變量成員, 所以定義索引器時, 也要使 用 get 和 set 訪問函數(shù), 不同的是使用索引器取得的是類實例中數(shù)組對象的各 元素的值, 而不是特定的數(shù)據(jù)成員。 定義屬性時需要定義屬性的名稱, 而定義索 引器時不需要給出具體的名稱,

28、 只需要使用關(guān)鍵字 this, 它用于引用當前的對象 實例。索引器的聲明: 修飾符 數(shù)據(jù)類型 thisint indexget 訪問器索引器的 get 訪問器體與方法體類似。 它返回索引器的類型。 get 訪問 器使用與索引器相同的 formal-index-parameter-list 。例如:get return ScoreArrayindex;set 訪問器索引器的 set 訪問器體與方法體類似。除了value 隱式參數(shù)外,它還使用與索引器相同的 formal-index-parameter-list 。例如:setScoreArrayindex = value; 示例 5:此示例聲明私

29、有數(shù)組字段 ScoreArray 和一個索引器。通過使用索引器可直接訪 問實例 bi 。另一種使用索引器的方法是將數(shù)組聲明為 public 成員并直接訪 問它的成員 ScoreArrayi 。using System;class IndexerClassprivate int ScoreArray = new int10;public int this int index/ 索引器的聲明get/ 檢查索引器的范圍if (index = 10) return 0;elsereturn ScoreArrayindex;setif (!(index = 10) ScoreArrayindex = v

30、alue;public class MainClasspublic static void Main()IndexerClass b = new IndexerClass();/ 調(diào)用索引器初始化數(shù)組中的第 4 個和第 6 個元素b3 = 256;b5 = 1024;for (int i=0; i&avingftccount厲肌沁儲戶的月利息6.666667,余額為* 2006-66? 邁“釵儲戶的月利息為12.5,余額為:3012-5wllyCs csc indexc lassIztuixjwof七 Visual Ctt .NET Compiler uer-sion ?_00_946& or

31、 Microsoft CR .NET Framework version 1_0_3705 安權(quán)所有 Microsoft Corporation 2001 &保留所肴權(quán)利兀一兀元元兀元兀元41tt2tt3tt4ttstt6#70 1 tt8tt9ttl4tl 元元元元6 25 02010:xMyCs 九、運算符重載 所有一元和二元運算符都具有可自動用于任何表達式的預(yù)定義實現(xiàn)。 除了預(yù)定義 實現(xiàn)外,還可通過在類或結(jié)構(gòu)中包括 operator聲明來引入用戶定義的實現(xiàn)。用 戶定義的運算符實現(xiàn)的優(yōu)先級總是高于預(yù)定義運算符實現(xiàn): 僅當沒有適用的用戶 定義運算符實現(xiàn)時才會考慮預(yù)定義運算符實現(xiàn)?!翱芍剌d的一元運算符”有:+ - ! + - true false“可重載的二元運算符”有:+ - * / % & | A =!= = =只有以上所列的運算符可以重載。具體說來,不可能重載成員訪問、方法調(diào)用或=、& |、?:、checked、unchecked、new typeof、as 和 is 運算符。當重載二元運算符時,也會隱式重載相應(yīng)的賦值運算符(若有)。例如,運算符*的重載也是運算符*=的重載。請注意,賦值運算符本身(=)無法重載。賦 值總是簡單地將值按位復(fù)制到變量中。示例 6:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論