C#程序設(shè)計實用教程_第1頁
C#程序設(shè)計實用教程_第2頁
C#程序設(shè)計實用教程_第3頁
C#程序設(shè)計實用教程_第4頁
C#程序設(shè)計實用教程_第5頁
已閱讀5頁,還剩156頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第5章

面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)2010-11-19面向?qū)ο蟮能浖_發(fā)技術(shù)是當(dāng)今計算機技術(shù)發(fā)展的重要成果和趨勢之一。C#是完全面向?qū)ο蟮某绦蛟O(shè)計語言。類和對象是面向?qū)ο蟪绦蛟O(shè)計中的重要概念。封裝性、繼承性和多態(tài)性是面向?qū)ο蟮奶攸c。本章主要介紹面向?qū)ο蟪绦蛟O(shè)計中的基本概念和基于C#的面向?qū)ο蟪绦蛟O(shè)計的方法。2023/2/42C#程序設(shè)計實用教程基本概念

5.1面向?qū)ο蟾攀?/p>

5.1.1面向?qū)ο蟮母拍蠲嫦驅(qū)ο蟪绦蛟O(shè)計(Object-OrientedProgramming)簡稱OOP技術(shù)。面向?qū)ο缶幊碳夹g(shù)是計算機編程技術(shù)中一次重大的進步。在面向?qū)ο缶幊碳夹g(shù)出現(xiàn)之前,程序的設(shè)計普遍采用的是面向過程的程序設(shè)計方法。2023/2/43C#程序設(shè)計實用教程5.1.1面向?qū)ο蟮母拍頞OP是一種系統(tǒng)化的程序設(shè)計方法,強調(diào)直接以問題域(即現(xiàn)實世界)中的事物為中心來考慮問題,并按照這些事物的本質(zhì)特征把它們抽象為對象。OOP的主要思想是將數(shù)據(jù)及處理這些數(shù)據(jù)的操作都封裝(Encapsulation)到一個稱為類(Class)的數(shù)據(jù)結(jié)構(gòu)中。使用這個類時,只需要定義一個類的變量即可,這個變量(Object)。通過調(diào)用對象的數(shù)據(jù)成員完成對類的使用。在這種方法下,編程人員不需要過分關(guān)注“如何做”,而是重點關(guān)注“做什么”。OOP編程思想較好地適應(yīng)了現(xiàn)實世界中的問題,因而得以廣泛應(yīng)用。2023/2/44C#程序設(shè)計實用教程5.1.2面向?qū)ο笳Z言的特點

面向?qū)ο蟮木幊谭绞骄哂欣^承、封裝和多態(tài)性等特點。(1)繼承在生活中,事物有很多的相似性,這種相似性是人們理解紛繁事物的一個基礎(chǔ)。因為事物之間往往具有某種“繼承”關(guān)系。比如,兒子和父親往往有許多相似之處,因為兒子從父親那里遺傳了許多特性;2023/2/45C#程序設(shè)計實用教程5.1.2面向?qū)ο笳Z言的特點

繼承(inheritance)是面向?qū)ο缶幊碳夹g(shù)的一塊基石,通過它可以創(chuàng)建分等級層次關(guān)系的類。繼承是父類和子類之間共享數(shù)據(jù)和方法的機制,通常把父類稱為基類,子類稱為派生類。子類可以從其父類中繼承屬性和方法,通過這種關(guān)系模型可以簡化類的設(shè)計。。2023/2/46C#程序設(shè)計實用教程5.1.2面向?qū)ο笳Z言的特點

例如,可以將水果看作一個父類,那么水果類具有顏色屬性。然后再定義一個香蕉類,在定義香蕉類時就不需要定義香蕉類的顏色屬性,通過如下繼承關(guān)系可以使香蕉類具有顏色屬性。class水果類{ Public顏色;//在水果類中定義顏色屬性}class香蕉類

:水果類{ //香蕉類中其他的屬性和方法}2023/2/47C#程序設(shè)計實用教程水果類顏色水果類顏色香蕉類香蕉類的其它屬性和方法5.1.2面向?qū)ο笳Z言的特點

(2)封裝類是屬性和方法的集合,為了實現(xiàn)某項功能而定義類后,開發(fā)人員并不需要了解類體內(nèi)每行代碼的具體涵義,只需通過對象來調(diào)用類內(nèi)某個屬性或方法即可實現(xiàn)某項功能,這就是類的封裝。封裝提供了外界與對象進行交互的控制機制,設(shè)計和實施者可以公開外界需要直接操作的屬性和方法,而把其他的屬性和方法隱藏在對象內(nèi)部。這樣可以讓軟件程序封裝化,而且可以避免外界錯誤地使用屬性和方法。2023/2/48C#程序設(shè)計實用教程5.1.2面向?qū)ο笳Z言的特點

(3)多態(tài)性類的多態(tài)(polymorph)指對于屬于同一個類的對象,在不同的場合能夠表現(xiàn)出不同的特征。多態(tài)性主要指在一般類中定義的屬性或行為,被特殊類繼承之后,可以具有不同數(shù)據(jù)類型或表現(xiàn)出不同的行為。這使得同一個屬性或行為在一般類及其各個特殊類具有不同的意義。例如:某個對象,其基類為“筆”,在調(diào)用它的“寫”方法時,程序會自動判斷出它的具體類型,如果是毛筆,則調(diào)用毛類對應(yīng)的“寫”方法,如果是鉛筆,則調(diào)用鉛筆對應(yīng)的“寫”方法。2023/2/49C#程序設(shè)計實用教程

5.2定義類

在C#中,“類”是一種數(shù)據(jù)結(jié)構(gòu),它可以包含數(shù)據(jù)成員(常量和字段)、函數(shù)成員(方法、屬性、事件、索引器、運算符、構(gòu)造函數(shù)、析構(gòu)函數(shù))。類是個靜態(tài)的概念,如果要使用某個類,就應(yīng)該定義該類的一個或多個實例,每一個實例就是一個對象。2023/2/410C#程序設(shè)計實用教程

5.2.1類的概念

類是對象概念在面向?qū)ο缶幊陶Z言中的反映,是相同對象的集合。類描述了一系列在概念上有相同含義的對象,并為這些對象統(tǒng)一定義了屬性和方法。類是對象的抽象描述和概括。例如:汽車是一個類,只要是汽車都有車牌,顏色,車輪、車門、發(fā)動機等特性,都可以加速,剎車,轉(zhuǎn)方向等行為。這是將所有的汽車進行歸納之后得出的共有的特性,但這些特性都是抽象的,非常不具體,只是用來描述一個類別,并不能具體指一輛汽車。而具體到某輛汽車就是一個對象了,例如:車牌照為蘇A2345**的黑色奧迪轎車,這就是汽車類的一個汽車對象。用具體的屬性可以在汽車類中唯一確定自己,并且對象具有類的操作2023/2/411C#程序設(shè)計實用教程

5.2.1類的概念

在C#中,所有的內(nèi)容都被封裝在類中,類是C#的基礎(chǔ),每個類通過屬性和方法及其他一些成員來表達事物的狀態(tài)和行為。事實上,編寫C#程序的主要任務(wù)就是定義各種類及類的各種成員。2023/2/412C#程序設(shè)計實用教程

5.2.2類的聲明

簡單地講,類是一種數(shù)據(jù)結(jié)構(gòu),用于模擬現(xiàn)實中存在的對象和關(guān)系,包含靜態(tài)的屬性和動態(tài)的方法。下面來看如何聲明類及其屬性、方法。在聲明一個類之前,需要向工程中新添加一個文件。2023/2/413C#程序設(shè)計實用教程

5.2.2類的聲明

1.向工程添加新項目在VS.NET中添加一個新的類文件以及其他新項目。操作很簡單,具體步驟如下:(1)在【解決方案瀏覽器】視圖中,在工程上單擊右鍵,再在打開的快捷菜單中選擇【添加】→【類】,如圖5-1所示。2023/2/414C#程序設(shè)計實用教程

5.2.2類的聲明

(2)在此時彈出的對話框中選擇添加類文件,并為新文件命名,以.cs作為后綴,如圖5-2所示。(3)單擊【打開】按鈕后,就可以在【解決方案瀏覽器】視圖中看到這個新的類文件了。(4)雙擊該類文件,可以在其中聲明新的類。當(dāng)然,也可以把多個功能類似的類放在一個類文件中。2023/2/415C#程序設(shè)計實用教程

5.2.2類的聲明

2.聲明類C#中類的聲明需要使用class關(guān)鍵字,并把類的主體放在花括號中,格式如下:[類修飾符]class類名

[:基類類名]{ //屬性 //方法}其中,除了class關(guān)鍵字和類名外,剩余的都是可選項;類名必須是合法的C#標(biāo)識符,它將作為新定義的類的類型標(biāo)識符。2023/2/416C#程序設(shè)計實用教程

5.2.2類的聲明

注意:class關(guān)鍵字前面是訪問級別。在C#中,類的訪問級別由類的修飾符進行限定,類的修飾符如表5-1所示。在上例中,如果類的修飾符為public,這表示該類可以被任何其他類訪問。類的名稱位于class關(guān)鍵字的后面。2023/2/417C#程序設(shè)計實用教程

5.2.2類的聲明

以上的類修飾符可以兩個或多個組合起來使用,但需要注意下面幾點:(1)

在一個類聲明中,同一類修飾符不能多次出現(xiàn),否則會出錯。。2023/2/418C#程序設(shè)計實用教程

5.2.2類的聲明

(2)在使用public、protected、internal和private這些類修飾符時,要注意這些類修飾符不僅表示所定義類的訪問特性,而且還表明類中成員聲明中的訪問特性,并且它們的可用性也會對派生類造成影響。(3)如果省略類修飾符,則默認為私有修飾符private。(4)對于具有繼承關(guān)系的類才有基類。如果一個類沒有從任何類繼承,就不需要基類類名選項。在C#中,一個類只能從另一個類中繼承。2023/2/419C#程序設(shè)計實用教程

5.2.2類的聲明

下面以一個學(xué)生類的實例,說明該類在C#中的實現(xiàn)。該類的類圖如圖5-3所示?!纠?-1】定義一個學(xué)生類。publicclassStudent{//屬性//學(xué)號、姓名、年齡等

//方法//長大、入學(xué)、畢業(yè)等}

2023/2/420C#程序設(shè)計實用教程

5.2.3類的靜態(tài)特性

屬性(或字段)可以看作是類的靜態(tài)描述,同樣,在定義屬性時,也可以使用訪問修飾符來定義其訪問級別。屬性的定義格式如下:

[修飾符]數(shù)據(jù)類型屬性名;其中,屬性修飾符attribe-modifier包括public、private、protected。下面的例子用來說明public和private修飾符的作用。

2023/2/421C#程序設(shè)計實用教程

5.2.3類的靜態(tài)特性

2023/2/422C#程序設(shè)計實用教程【例5-2】public和private修飾符的作用。usingSystem;

namespaceExample_PublicAndPrivate{///學(xué)生類publicclassStudent{

//屬性

publicstringstrName;//公有屬性

privateintnAge; //私有屬性

//方法...}///Main函數(shù)類classTest{///應(yīng)用程序的主入口點。staticvoidMain(string[]args){Students=newStudent();s.strName="張三“;//正確s.nAge=20;//錯誤,不能訪問}}}

5.2.3類的靜態(tài)特性

上述程序中,定義一個Student類,包含一個公有屬性“strName”和一個私有屬性“nAge”。在Test類中,試圖對學(xué)生類的對象s的年齡進行設(shè)置,但是Student類的nAge屬性是私有的,在其他的類中無法訪問,因此程序會報錯,報錯信息如圖5-4所示。而訪問其公有屬性strName就不會有問題。2023/2/423C#程序設(shè)計實用教程

5.2.4類的動態(tài)行為:方法

類的屬性是客觀世界實體性質(zhì)的抽象,而方法是實體所能執(zhí)行的操作。下面來看如何聲明其動態(tài)方法。同屬性一樣,類的方法也具有訪問屬性,如public、private、protected等,其定義格式如下:

[修飾符]返回類型方法名(參數(shù)列表);下面的例子為Student類定義了公有方法SetAge()和GetAge(),用于設(shè)置和獲取其靜態(tài)屬性“年齡”。2023/2/424C#程序設(shè)計實用教程

5.2.4類的動態(tài)行為

【例5-3】類的公有方法的示例。usingSystem;

namespaceDeclareMethod{///學(xué)生類publicclassStudent{//屬性

publicstringstrName; //公有屬性privateintnAge; //私有屬性

//方法...publicvoidSetAge(int_nAge){this.nAge=_nAge;}

2023/2/425C#程序設(shè)計實用教程

5.2.4類的動態(tài)行為

publicintGetAge(){returnthis.nAge;}}

///Main函數(shù)類classClass1{staticvoidMain(string[]args){Students=newStudent();s.SetAge(20);

//賦值年齡Console.WriteLine(s.GetAge()); //獲取年齡}}}2023/2/426C#程序設(shè)計實用教程

5.2.4類的動態(tài)行為

程序中為各個學(xué)生定義了公有方法SetAge(),其功能是為類的私有屬性“年齡”賦值;同時為學(xué)生類定義了獲取“年齡”屬性值的公有方法GetAge()。通過SetAge()方法,并傳遞適當(dāng)?shù)膮?shù),便可以為學(xué)生s的年齡賦值,而通過調(diào)用GetAge()方法獲取其年齡,并輸出。2023/2/427C#程序設(shè)計實用教程

5.2.5創(chuàng)建類的實例-對象

類是現(xiàn)實世界中對象或者關(guān)系的模擬,是一個抽象的概念。例如,像“學(xué)生”這個概念,世界上并沒有一個叫做“學(xué)生”的活生生的東西,而只有“張三”或者“李四”這些具體的學(xué)生實例,這反應(yīng)了類和對象的關(guān)系。(1)類是具有相同或相似結(jié)構(gòu)、操作和約束規(guī)則的對象組成的集合。(2)對象是某一類的具體化實例,每一個類都具有某些共同特征對象的抽象。C#使用new關(guān)鍵字來實現(xiàn)實例化類得到一個具體的對象,其格式如下:

類名對象名=new類名([參數(shù)列表]);在前面的示例中已經(jīng)用到創(chuàng)建類實例,都是使用new關(guān)鍵字得到一個具體的學(xué)生對象。如下列代碼所示:

Students=newStudent();2023/2/428C#程序設(shè)計實用教程對象的使用【例5-2】public和private修飾符的作用。usingSystem;

namespaceExample_PublicAndPrivate{///學(xué)生類publicclassStudent{

//屬性

publicstringstrName;//公有屬性

privateintnAge; //私有屬性

//方法...}///Main函數(shù)類classTest{///應(yīng)用程序的主入口點。staticvoidMain(string[]args){Students=newStudent();s.strName="張三“;//正確s.nAge=20;//錯誤,不能訪問}}}

5.2.6繼承類

繼承的本質(zhì)是代碼重用。當(dāng)要構(gòu)造一個新的類時,通常無需從頭開始。例如,在學(xué)生類的基礎(chǔ)上,可以建立一個“大學(xué)生”類。很明顯,“大學(xué)生”這個類具有自己的新特點,如“所在系”就并不是所有的學(xué)生都有的,而是大學(xué)生才有的特殊性質(zhì)。因此,可以把大學(xué)生看作是學(xué)生的一種延續(xù),即在繼承了學(xué)生的屬性和方法基礎(chǔ)之上,又包含了新的屬性或方法。在構(gòu)造大學(xué)生這個類時,只需在學(xué)生類的基礎(chǔ)上添加大學(xué)生特有的特性即可,而無需從頭開始。此時,稱學(xué)生類為父類,大學(xué)生類為子類。在C#中,用符號“:”來實現(xiàn)類的繼承。2023/2/430C#程序設(shè)計實用教程

5.2.6繼承類

【例5-4】類繼承的示例。usingSystem;

namespaceExample_Inheritance{ ///學(xué)生類 publicclassStudent{publicstringstrName; //姓名publicintnAge; //年齡}

2023/2/431C#程序設(shè)計實用教程

5.2.6繼承類

///大學(xué)生類:繼承學(xué)生類publicclassCollegeStudent:Student{publicstringstrInsititute; //所在系

}

2023/2/432C#程序設(shè)計實用教程

5.2.6繼承類

///程序入口:主函數(shù)類publicclassMainClass{///主函數(shù)staticvoidMain(string[]args){Students=newStudent();s.strName="xiaobao";s.nAge=18;Console.WriteLine("姓名:{0},年齡{1}",s.strName,s.nAge);

2023/2/433C#程序設(shè)計實用教程

5.2.6繼承類

//使用子類Console.WriteLine("-------------使用子類-------------");CollegeStudentc=newCollegeStudent();c.strName="小寶";c.nAge=23;c.strInsititute="計算機系";Console.WriteLine("姓名:{0},年齡:{1}歲,所屬系:{2}",c.strName,c.nAge,c.strInsititute);Console.ReadKey();}}}2023/2/434C#程序設(shè)計實用教程

5.2.6繼承類

程序運行結(jié)果如圖5-5所示。注意:此時,大學(xué)生類具有學(xué)生類的所有屬性和方法,另外,還具有其獨自的屬性——所在系。不難看出,繼承就是指一個子類能夠直接獲得父類的性質(zhì)或特征,而不必重復(fù)定義。顯然,繼承具有傳遞性。另外,C#只支持單繼承,即一個類只能繼承一個父類。2023/2/435C#程序設(shè)計實用教程

5.3構(gòu)造函數(shù)和析構(gòu)函數(shù)

在實際應(yīng)用中,方法的定義和調(diào)用是很復(fù)雜的。在此,將從兩個特殊的方法(構(gòu)造函數(shù)和析構(gòu)函數(shù))入手,對其進行進一步的討論。在C#中,構(gòu)造函數(shù)是當(dāng)類實例化時首先執(zhí)行的函數(shù)。反之,析構(gòu)函數(shù)是當(dāng)實例(也就是對象)從內(nèi)存中銷毀前最后執(zhí)行的函數(shù)。這兩個函數(shù)的執(zhí)行是無條件的,并且不需要程序手工干預(yù)。也就是說,只要定義一個對象或銷毀一個對象,不用顯式地調(diào)用構(gòu)造函數(shù)或析構(gòu)函數(shù),系統(tǒng)都會自動在創(chuàng)建對象時調(diào)用構(gòu)造函數(shù),而在銷毀對象時調(diào)用析構(gòu)函數(shù)。2023/2/437C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

在實例化對象的時候,對象的初始化是自動完成的,并且這個對象是空的。有時,我們希望創(chuàng)建一個對象時要為其初始化某些特征,這時就需要用到構(gòu)造函數(shù)。在C#中,構(gòu)造函數(shù)是特殊的成員函數(shù)。構(gòu)造函數(shù)的特殊性表現(xiàn)在如下幾個方面:(1)構(gòu)造函數(shù)的函數(shù)名和類的名稱一樣。(2)構(gòu)造函數(shù)可以帶參數(shù),但沒有返回值。(3)構(gòu)造函數(shù)在對象定義時被自動調(diào)用。2023/2/438C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

(4)如果沒有給類定義構(gòu)造函數(shù),則編譯系統(tǒng)會自動生成一個默認的構(gòu)造函數(shù)。(5)構(gòu)造函數(shù)可以被重載,但不可以被繼承。(6)構(gòu)造函數(shù)的類型修飾符總是public。如果是private,則表示這個類不能被實例化,這通常用于只含有靜態(tài)成員的類中。2023/2/439C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

【例5-5】通過構(gòu)造函數(shù),實現(xiàn)在產(chǎn)生一個學(xué)生對象時為其完成起名工作。usingSystem;

namespaceExample_Construct{///<summary>///學(xué)生類///</summary>publicclassStudent{publicstringstrName; //域

2023/2/440C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

///<summary>///構(gòu)造函數(shù),為學(xué)生起名///</summary>publicStudent(string_strName){this.strName=_strName;}

}classClass1{

staticvoidMain(string[]args){Students=newStudent("張三");Console.WriteLine(s.strName);}}}2023/2/441C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

注意:在Student類中,定義了方法Student(),注意這個方法與Student類同名。這樣,每當(dāng)實例化一個Student對象時,總會執(zhí)行這個函數(shù)。在構(gòu)造函數(shù)中可以沒有參數(shù),也可以有一個或多個參數(shù)。這表明構(gòu)造函數(shù)在類的聲明中可以有函數(shù)名相同,但參數(shù)個數(shù)不同或者參數(shù)不同的多種形式,這就是構(gòu)造函數(shù)重載。用new關(guān)鍵字創(chuàng)建一個類的對象時,類名后的一對圓括號提供初始化列表,這實際上就是提供給構(gòu)造函數(shù)的參數(shù)。系統(tǒng)根據(jù)這個初始化列表的參數(shù)個數(shù)、參數(shù)類型和參數(shù)順序調(diào)用不同的構(gòu)造函數(shù)。2023/2/442C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

【例5-6】實現(xiàn)Time類的構(gòu)造函數(shù)及其重載。usingSystem;

namespaceExample_ConstructOverload{classTime{publicintnHour,nMinute,nSecond;publicTime(){nHour=nMinute=nSecond=0;}

2023/2/443C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

publicTime(intHour){nHour=Hour;nMinute=nSecond=0;}publicTime(intHour,intMinute){nHour=Hour;nMinute=Minute;nSecond=0;}2023/2/444C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

publicTime(intHour,intMinute,intSecond){nHour=Hour;nMinute=Minute;nSecond=Second;}}classTest{staticvoidMain(){Timet1,t2,t3,t4;2023/2/445C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

//對t1,t2,t3,t4分別調(diào)用不同的構(gòu)造函數(shù)t1=newTime();t2=newTime(10);t3=newTime(10,30);t4=newTime(10,30,30);Console.WriteLine("t1的時間為:{0}時{1}分鐘{2}秒",t1.nHour,t1.nMinute,t1.nSecond);Console.WriteLine("t2的時間為:{0}時{1}分鐘{2}秒",t2.nHour,t2.nMinute,t2.nSecond);Console.WriteLine("t3的時間為:{0}時{1}分鐘{2}秒",t3.nHour,t3.nMinute,t3.nSecond);Console.WriteLine("t4的時間為:{0}時{1}分鐘{2}秒",t4.nHour,t4.nMinute,t4.nSecond);}}}2023/2/446C#程序設(shè)計實用教程

5.3.1構(gòu)造函數(shù)

程序運行結(jié)果如圖5-6所示。注意:實例對象創(chuàng)建時,根據(jù)不同的參數(shù)調(diào)用相應(yīng)的構(gòu)造函數(shù)完成初始化。2023/2/447C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

前面,介紹了使用構(gòu)造函數(shù)在實例化對象時自動完成一些初始化工作。反之,在銷毀對象時,有時候也希望能自動一些做“收尾”任務(wù),例如關(guān)閉數(shù)據(jù)庫連接等。C#使用析構(gòu)函數(shù)來完成這個功能。2023/2/448C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

析構(gòu)函數(shù)也是類的特殊的成員函數(shù),它主要用于釋放類實例。析構(gòu)函數(shù)的特殊性表現(xiàn)在以下幾個方面:(1)析構(gòu)函數(shù)的名字也與類名相同,只是需要在其前面加了一個符號“~”。(2)析構(gòu)函數(shù)不接收任何參數(shù),沒有任何返回值,也沒有任何訪問關(guān)鍵字。(3)當(dāng)撤銷對象時,自動調(diào)用析構(gòu)函數(shù)。(4)析構(gòu)函數(shù)不能被繼承,也不能被重載。注意:另外,如果試圖聲明其他不與類名相同,但是以“~”開頭的方法,編譯器會產(chǎn)生錯誤。2023/2/449C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

【例5-7】為Student類建立析構(gòu)函數(shù)。publicclassStudent{///<summary>///析構(gòu)函數(shù)///</summary>~Student(){Console.WriteLine("CallDestructMethod.");}}當(dāng)程序使用完一個學(xué)生對象后,都會自動調(diào)用這個析構(gòu)函數(shù),輸出“CallDestructMethod.”。2023/2/450C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

說明:事實上,一般并不需要使用析構(gòu)函數(shù),.NETFramework提供了默認的析構(gòu)函數(shù)執(zhí)行內(nèi)存清理等工作。如果確定需要在銷毀對象前,完成一些特殊的任務(wù),才需要使用自定義的析構(gòu)函數(shù)。2023/2/451C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

【例5-8】構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用。usingSystem;

namespaceExample_ConstructAndDestruct{classPoint{intx,y,z;publicPoint(){this.z=0;}2023/2/452C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

publicPoint(intx,inty){this.x=x;this.y=y;this.z=x+y;}publicint_Z //屬性{get{returnthis.z;}set{this.z=value;}}2023/2/453C#程序設(shè)計實用教程

5.3.2析構(gòu)函數(shù)

~Point(){Console.WriteLine("~Point()isbeingcalled.");}}classTest{staticvoidMain(){Pointp1=newPoint(1,5);Pointp2=newPoint();Console.WriteLine("p1.z="+p1._Z);Console.WriteLine("p2.z="+p2._Z);}}}2023/2/454C#程序設(shè)計實用教程

5.4方法

在前面,對類的方法進行了簡單的介紹,也對特殊的類方法——構(gòu)造和析構(gòu)函數(shù)進行了介紹。在實際應(yīng)用中,方法的定義和調(diào)用要復(fù)雜得多。本節(jié)將從輸入?yún)?shù)、方法重載等方面,對其進行進一步的討論。2023/2/455C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

方法是類中用于執(zhí)行計算或進行其他操作的函數(shù)成員。1.方法的定義方法由方法頭和方法體組成,其一般定義的格式為:修飾符返回值類型方法名(形式參數(shù)列表){

方法體各語句;}2023/2/456C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

說明:(1)如果省略“方法修飾符”,默認為private,表示該方法為類的私有成員。(2)“返回值類型”指定該方法返回數(shù)據(jù)的類型,它可以是任何有效的類型,C#通過方法中的return語句得到返回值。如果方法不需要返回一個值,其返回值類型必須是void。(3)方法名要求滿足C#標(biāo)識符的命名規(guī)則,括號()是方法的標(biāo)志,不能省略。(4)“方法參數(shù)列表”是逗號分隔的類型、標(biāo)識符對。這里的參數(shù)是形式參數(shù),本質(zhì)是一個變量,它用來在調(diào)用方法時接收傳給方法的實際參數(shù)的值。如果方法沒有參數(shù),那么參數(shù)列表為空。2023/2/457C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

【例5-9】方法的定義。classMotorcycle{publicvoidStartEngine(){}publicvoidAddGas(intgallons){}publicintDrive(intmiles,intspeed){return0;}}2023/2/458C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

2.方法的調(diào)用調(diào)用對象的方法類似于訪問字段。在對象名稱名稱之后,依次添加句點、方法名稱和括號。參數(shù)在括號內(nèi)列出,并用逗號隔開。因此,可以如下例來調(diào)用Motorcycle類的方法?!纠?-10】方法的調(diào)用。Motorcyclemoto=newMotorcycle();moto.StartEngine();moto.AddGas(15);moto.Drive(5,20);2023/2/459C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

3.從方法返回一般來說有兩種情況將導(dǎo)致方法返回。(1)當(dāng)遇到方法的結(jié)束花括號。(2)執(zhí)行到return語句。有兩種形式的return語句:一種用在void方法中(即無需有返回值的方法),另一種用在有返回值的方法中。2023/2/460C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

【例5-11】通過方法的結(jié)束花括號返回。usingSystem;

namespaceMethod{classMyClass{publicvoidmyMethod(){inti;for(i=0;i<10;i++){if(i%3==0)continue;Console.WriteLine("{0}\t",i);}}

2023/2/461C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

staticvoidMain(){MyClassmycls=newMyClass();mycls.myMethod();}}}程序的運行結(jié)果為:1245782023/2/462C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

【例5-12】通過方法的return語句返回。usingSystem;

namespaceMethod{classMyClass{publicvoidmyMethod(){inti=8;if(i>=5){i=i*2;Console.WriteLine(i);return;}else{i=i*3;Console.WriteLine(i);return;}}staticvoidMain(){MyClassmycls=newMyClass();mycls.myMethod();}}}2023/2/463C#程序設(shè)計實用教程

5.4.1方法的定義及調(diào)用

使用下述形式的return語句從方法返回一個值給調(diào)用者:格式:returnvalue;【例5-13】通過方法的return語句返回值。usingSystem;

namespaceMethod{classMyClass{publicintmyMethod(){inti=8;if(i>=5){i=i*2;returni;}

else{i=i*3;returni;}}staticvoidMain(){MyClassmycls=newMyClass();Console.WriteLine(mycls.myMethod());}}}2023/2/464C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

調(diào)用方法時,可以給方法傳遞一個或多個值。傳給方法的值稱為實參(argument),在方法內(nèi)部,接收實參值的變量稱為形參(parameter),形參在緊跟著方法名的括號中聲明。形參的聲明語法與變量的聲明語法一樣。形參只在方法內(nèi)部有效,除了將接收實參的值外,它與一般的變量沒什么區(qū)別。C#方法的參數(shù)類型主要有:值參數(shù)、引用參數(shù)、輸出參數(shù)和參數(shù)數(shù)組。2023/2/465C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

1.值參數(shù)沒有用任何修飾符聲明的參數(shù)為值參數(shù),它表明實參與形參之間按值傳遞。當(dāng)這個方法被調(diào)用時,編譯器為值參數(shù)分配存儲單元,然后將對應(yīng)的實參的值拷貝到形參中。實參可以是變量、常量、表達式,但要求其值的類型必須與形參聲明的類型相同或者能夠被隱式地轉(zhuǎn)化為這種類型。這種傳遞方式的好處是在方法中對形參的修改不會影響外部的實參,也就是說數(shù)據(jù)只能傳入方法而不能從方法傳出。2023/2/466C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

【例5-14】使用值參數(shù)。usingSystem;

namespaceValueParameters{classMyClass{publicvoidSwap(intx,inty){intk;k=x;x=y;y=k;}}

2023/2/467C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

classTest{staticvoidMain(){inta=8,b=10;Console.WriteLine("a={0},b={1}",a,b);MyClassmycls=newMyClass();mycls.Swap(a,b);Console.WriteLine("a={0},b={1}",a,b);}}}程序的運行結(jié)果為:a=8,b=10a=8,b=102023/2/468C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

2.引用參數(shù)用ref修飾符聲明的參數(shù)為引用參數(shù)。引用參數(shù)與值參數(shù)不同,引用參數(shù)并不創(chuàng)建新存儲單元,它與方法調(diào)用中的實參變量同處一個存儲單元。因此,在方法內(nèi)對形參的修改就是對外部實參變量的修改。在函數(shù)調(diào)用中,引用參數(shù)必須被賦初值。在調(diào)用時,傳遞給ref參數(shù)的必須是變量,類型必須相同,并且必須使用ref修飾。2023/2/469C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

【例5-15】使用引用參數(shù)。usingSystem;

namespaceReferenceParameters{classMyClass{publicvoidSwap(refintx,refinty){intk;k=x;x=y;y=k;}}2023/2/470C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

classTest{staticvoidMain(){inta=8,b=10;Console.WriteLine("a={0},b={1}",a,b);MyClassmycls=newMyClass();mycls.Swap(refa,refb);Console.WriteLine("a={0},b={1}",a,b);}}}程序的運行結(jié)果為:a=8,b=10a=10,b=82023/2/471C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

3.輸出參數(shù)用out修飾符定義的參數(shù)稱為輸出參數(shù)。如果希望方法返回多個值,可使用輸出參數(shù)。輸出參數(shù)與引用參數(shù)類似,它也不產(chǎn)生新的存儲空間。兩者的區(qū)別在于:out參數(shù)只能用于從方法中傳出值,而不能從方法調(diào)用處接受實參數(shù)值;在方法體內(nèi)out參數(shù)被認為是未賦過值的,所以在方法結(jié)束之前應(yīng)該對out參數(shù)賦值。2023/2/472C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

【例5-16】使用輸出參數(shù)。usingSystem;

namespaceOutputParameters{publicclassStudent{publicstringstrName;//姓名publicintnAge;//年齡

///構(gòu)造函數(shù)publicStudent(string_strName,int_nAge){strName=_strName;nAge=_nAge;}

2023/2/473C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

///長大_nSpan歲publicvoidGrow(int_nSpan,outint_nOutCurrentAge){nAge+=_nSpan;_nOutCurrentAge=nAge;}}publicclassTest{staticvoidMain(){Students=newStudent("張三",21);intnCurrentAge;s.Grow(3,outnCurrentAge);Console.WriteLine(s.nAge);//輸出24}}}2023/2/474C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

程序的輸出結(jié)果如下:24注意:在上例中,在調(diào)用時需要在輸入?yún)?shù)前加out關(guān)鍵字。2023/2/475C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

4.參數(shù)數(shù)組有時候,在調(diào)用一個方法時,預(yù)先不能確定參數(shù)的數(shù)量、數(shù)據(jù)類型等,怎么辦呢?一種解決方案是使用params關(guān)鍵字。params關(guān)鍵字指明一個輸入?yún)?shù),此輸入?yún)?shù)將被看作為一個參數(shù)數(shù)組,這種類型的輸入?yún)?shù)只能作為方法的最后一個參數(shù)。以下例說明其功能。2023/2/476C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

【例5-17】使用參數(shù)數(shù)組。usingSystem;

namespaceParameterArray{publicclassStudent{publicstringstrName; //姓名publicintnAge; //年齡publicSystem.Collections.ArrayListstrArrHobby=newSystem.Collections.ArrayList(); //愛好

2023/2/477C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

///<summary>///構(gòu)造函數(shù)///</summary>publicStudent(string_strName,int_nAge){this.strName=_strName;this.nAge=_nAge;}

///<summary>///為愛好賦值///</summary>publicvoidSetHobby(paramsstring[]_strArrHobby){for(inti=0;i<_strArrHobby.Length;i++)this.strArrHobby.Add(_strArrHobby[i]);}}

2023/2/478C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

classTest{staticvoidMain(string[]args){Students=newStudent("張三",20);

s.SetHobby("游泳","籃球","足球");

for(inti=0;i<s.strArrHobby.Count;i++)Console.WriteLine(s.strArrHobby[i]);}}}2023/2/479C#程序設(shè)計實用教程

5.4.2方法的參數(shù)

程序的輸出結(jié)果如下:

游泳

籃球

足球注意:上例為Student類實現(xiàn)了一個愛好賦值方法,用于確定學(xué)生的愛好。因為實現(xiàn)無法確定學(xué)生的愛好數(shù)目,因此可以使用params參數(shù)來接收多個字符串參數(shù),并整體作為數(shù)組傳遞給方法。2023/2/480C#程序設(shè)計實用教程

5.4.3方法的重載

有時,對于類需要完成的同一個功能,要求可能比較復(fù)雜。例如,對學(xué)生類而言,如果想要使其具有一個“成長”方法,但是這個方法,可能是使學(xué)生增加一歲,也可能是增加指定的歲數(shù),該如何解決這個問題呢?C#使用重載技術(shù)來完成這個功能。重載是指允許存在多個同名函數(shù),而這函數(shù)的參數(shù)不同(或許是參數(shù)個數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)。在調(diào)用這個方法時,編譯器可以按照輸入的參數(shù)去調(diào)用適當(dāng)?shù)姆椒?。下例所示代碼完成本節(jié)所提出的學(xué)生“成長”問題。2023/2/481C#程序設(shè)計實用教程

5.4.3方法的重載

【例5-18】方法的重載。usingSystem;

namespaceMethodOverload{///<summary>///學(xué)生類///</summary>publicclassStudent{//屬性

publicstringstrName; //姓名publicintnAge; //年齡

2023/2/482C#程序設(shè)計實用教程

5.4.3方法的重載

///<summary>///成長1歲///</summary>publicvoidGrow(){this.nAge++;}

///<summary>///成長_nAgeSpan歲///</summary>publicvoidGrow(int_nAgeSpan){this.nAge+=_nAgeSpan;}}

2023/2/483C#程序設(shè)計實用教程

5.4.3方法的重載

///<summary>///Main函數(shù)類///</summary>classClass1{staticvoidMain(string[]args){Students=newStudent();s.strName="張三";s.nAge=20;s.Grow();Console.WriteLine(s.nAge); //輸出21s.Grow(2);Console.WriteLine(s.nAge); //輸出23}}}2023/2/484C#程序設(shè)計實用教程

5.4.3方法的重載

程序運行如果如下: 21 23注意:在示例中,定義了學(xué)生類,在類中實現(xiàn)了兩個Grow()方法;前一個Grow()方法,沒有任何輸入?yún)?shù),其功能為使學(xué)生年齡加1,后一個同名方法Grow(),帶有一個參數(shù)_nAgeSpan,其功能為使學(xué)生年齡加nAgeSpan。在主函數(shù)中,分別調(diào)用學(xué)生類的Grow()方法,并輸入不同的參數(shù),從而得到不同的結(jié)果。這樣,就可以使用同樣的方法名,完成功能類似、具體實現(xiàn)不同的任務(wù)了。2023/2/485C#程序設(shè)計實用教程

5.4.4靜態(tài)方法和非靜態(tài)方法

使用static修飾符的方法稱為靜態(tài)方法,沒有使用static修飾符的方法稱為非靜態(tài)方法。靜態(tài)方法和非靜態(tài)方法的區(qū)別是:靜態(tài)方法表示類所具有的行為,而非其某個具體對象所具有的行為。例如學(xué)生分班這項任務(wù),就是全體學(xué)生集體的事情,而非某個學(xué)生的事情。靜態(tài)方法的訪問級別關(guān)鍵字同普通方法一樣,但是很少是private,因為一般需要在類的外部訪問類的靜態(tài)方法。在調(diào)用靜態(tài)方法時不需要實例化類的對象。直接使用類引用即可。2023/2/486C#程序設(shè)計實用教程

5.4.4靜態(tài)方法和非靜態(tài)方法

【例5-19】使用靜態(tài)方法和非靜態(tài)方法。usingSystem;

namespaceStaticMethod{classMyClass{publicinta;staticpublicintb;voidFun1()//定義一個非靜態(tài)方法{a=10;

//正確,直接訪問非靜態(tài)方法b=20;

//正確,直接訪問靜態(tài)方法}2023/2/487C#程序設(shè)計實用教程

5.4.4靜態(tài)方法和非靜態(tài)方法

staticvoidFun2()

//定義一個靜態(tài)方法{a=10;

//錯誤,不能訪問非靜態(tài)方法b=20;

//正確,可以訪問靜態(tài)成員,相當(dāng)于MyClass.b=20}}classTest{staticvoidMain(){MyClassclsA=newMyClass();clsA.a=10;

//正確,訪問類MyClass的非靜態(tài)公有成員clsA.b=20;

//錯誤,不能直接訪問類中靜態(tài)公有成員2023/2/488C#程序設(shè)計實用教程

5.4.4靜態(tài)方法和非靜態(tài)方法

MyClass.a=30;

//錯誤,不能通過類名訪問類中非靜態(tài)公有成員MyClass.b=40;

//正確,訪問類MyClass中靜態(tài)公有成員}}}2023/2/489C#程序設(shè)計實用教程

5.4.5運算符的重載

運算符也是C#類的一個成員,系統(tǒng)對大部分運算符都給出了常規(guī)定義,這些定義大部分和現(xiàn)實生活中這些運算符的意義相同。在實際應(yīng)用中,有些數(shù)據(jù)、結(jié)構(gòu)或類之間是沒有運算可言的,例如對一個姓名進行++操作是沒有意義的。但如果把一個班的全體學(xué)生的姓名存成一個數(shù)據(jù)庫,用string類型的變量name來存儲其中某個學(xué)生的姓名,那么編程人員總想進行name++操作來獲取下一個學(xué)生的姓名,這時就可以對++運算符進行重載。在C#中,運算符重載在類中進行聲明,并且通過調(diào)用類的成員方法來實現(xiàn)。2023/2/490C#程序設(shè)計實用教程

5.4.5運算符的重載

運算符重載聲明的格式為:返回類型operator重載的運算符(運算符參數(shù)列表){運算符重載的實現(xiàn)部分}和方法聲明一樣,返回類型可以根據(jù)函數(shù)實際需要設(shè)定為任意合法的C#類型修飾符。在方法實現(xiàn)部分通過return語句返回該數(shù)據(jù)類型。在C#中,可以重載的運算符主要有: +-!~

++--truefalse*/%|&^<<>>==<><=>=不能重載的運算符有: =&&||?:newtypeofsizeofis2023/2/491C#程序設(shè)計實用教程

5.4.5運算符的重載

【例5-20】假設(shè)空間的某一點的坐標(biāo)為(x,y,z),規(guī)定為~(x,y,z)關(guān)于原點的對稱。要實現(xiàn)這一功能,需要對一元運算符“~”進行重載。程序代碼如下:usingSystem;namespaceOperatorReload{classSpace{publicintx,y,z;publicSpace(intxx,intyy,intzz){x=xx;y=yy;z=zz;}2023/2/492C#程序設(shè)計實用教程

5.4.5運算符的重載

publicstaticSpaceoperator~(Spaced1){SpaceNeg=newSpace(0,0,0);Neg.x=(-1)*d1.x;Neg.y=(-1)*d1.y;Neg.z=(-1)*d1.z;returnNeg;}}

2023/2/493C#程序設(shè)計實用教程

5.4.5運算符的重載

classTest{publicstaticvoidMain(){Spaced1=newSpace(1,2,3);Spaced2=~d1;Console.WriteLine("空間坐標(biāo)(1,2,3)的關(guān)于對稱坐標(biāo)是:({0},{1},{2})。",d2.x,d2.y,d2.z);Console.Read();}}}程序運行如果如下:

空間坐標(biāo)(1,2,3)的關(guān)于對稱坐標(biāo)是:(-1,-2,-3)。2023/2/494C#程序設(shè)計實用教程

5.5屬性

在前面簡單介紹了類的靜態(tài)屬性,本節(jié)將對其做更深入的探討。2023/2/495C#程序設(shè)計實用教程

5.5.1字段和屬性

如果想把類的靜態(tài)特征分得更細,可以把其分為字段和屬性兩類。1、字段(Field)又稱為域,表示存儲位置。2、屬性(Attribute)在編程思想上真正實現(xiàn)了面向?qū)ο髮Α皩傩浴钡臏蚀_定義,不表示存儲位置,而是一個特殊的接口,用于對外交互類的靜態(tài)信息。具有兩個函數(shù):取值函數(shù)get(),獲取字段的值;賦值函數(shù)set(),為字段賦值,使用value關(guān)鍵字獲取用戶輸入。2023/2/496C#程序設(shè)計實用教程

5.5.1

溫馨提示

  • 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)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論