版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1.1.7面向?qū)ο蟾呒壣钲谑行畔⒙殬I(yè)技術(shù)學院類的繼承01目
錄Sealed關鍵字02多態(tài)03抽象類和接口04異常0506命名空間和程序集知識回顧類的定義及對象構(gòu)造方法this和static關鍵字面向?qū)ο蟮母拍钤L問修飾符垃圾回收嵌套類和匿名類對象初始化器學習目標通過本節(jié)學習可以:重點學習類的繼承重點學習多態(tài)重點學習抽象類和接口掌握sealed關鍵字掌握異常了解命名空間和程序集01類的繼承類的繼承繼承的概念在現(xiàn)實生活中,繼承一般指的是子女繼承父輩的財產(chǎn)。在程序中,繼承描述的是事物之間的所屬關系,通過繼承可以使多種事物之間形成一種關系體系。例如貓和狗都屬于動物,在程序中便可認為貓和狗繼承自動物,同理波斯貓和巴厘貓繼承自貓,而沙皮狗和斑點狗繼承自狗,這些動物之間會形成一個繼承體系。具體如下圖所示。類的繼承繼承的概念在C#中,類的繼承是指在一個現(xiàn)有類的基礎上去構(gòu)建一個新的類,構(gòu)建出來的新類被稱作子類,現(xiàn)有的類被稱作父類,子類會自動擁有父類所有可繼承的屬性和方法。例如動物和犬科的繼承關系,可以用如下代碼表示:classAnimal{}classDog:Animal{//Dog類繼承Animal類//Dog類可以自動擁有Animal類的屬性和方法}類的繼承繼承的概念在類的繼承中,需要注意一些問題,具體如下:繼承具有單一性,也就是說一個類只能有一個直接的父類,例如下面的語句是錯誤的。classA{}classB{}classC:A,B{}//C類不可以同時繼承A類和B類classA{}classB:A{}classC:A{}//類B和類C都可以繼承類A多個類可以繼承同一個父類,例如下面的語句是正確的。類的繼承繼承的概念在C#中,多層繼承是可以的,即一個類的父類可以再去繼承其他類,例如C類繼承自B類,B類又繼承自A類,此時C類也可稱作A類的子類,下面的語句是正確的。classA{}classB:A{}//B類繼承自A類,B類是A類的子類classC:B{}//C類繼承自B類,C類是B類的子類構(gòu)造方法的執(zhí)行過程構(gòu)造方法的執(zhí)行過程在上一章中學習了構(gòu)造方法的定義以及重載,了解到構(gòu)造方法可以用于初始化類的靜態(tài)成員和實例成員。在繼承關系中,構(gòu)造方法的執(zhí)行過程會變得有些不一樣,下面進行具體分析。當一個類的對象被創(chuàng)建時,如果該類擁有父類的話,在調(diào)用自身構(gòu)造方法的同時還會調(diào)用父類的構(gòu)造方法,其具體執(zhí)行過程如下圖所示。從圖中可以看出,子類在實例化對象時,首先會調(diào)用父類的構(gòu)造方法,然后再調(diào)用自身的構(gòu)造方法。隱藏基類方法隱藏基類方法子類在繼承父類時可以對父類的成員進行擴展,如果子類中出現(xiàn)與父類同名的方法,那么在調(diào)用該方法時程序就不能明確該方法是屬于父類還是子類,這時編譯器就會提示使用new關鍵字隱藏基類方法。接下來通過一個案例來演示如何隱藏基類方法。隱藏基類方法隱藏基類方法程序編譯出現(xiàn)警告,如下圖所示。根據(jù)程序編譯警告,將程序第9行代碼添加一個new關鍵字,修改后的代碼片段如下所示。classDog:Animal{publicnewvoidShout(){//與父類方法重名Console.WriteLine("汪汪......");}}添加new關鍵字隱藏基類方法隱藏基類方法運行結(jié)果,如下圖所示。在示例中,Dog類繼承Animal類,同時Dog類中存在與父類相同的方法Shout(),因此,使用new關鍵字可以明確告訴編譯器執(zhí)行Dog類中的Shout()方法,解決繼承關系中方法同名的問題。裝箱和拆箱裝箱和拆箱在實際開發(fā)過程中,某些方法的參數(shù)類型為引用類型,如果調(diào)用時傳入的是數(shù)值類型,此時需要進行裝箱操作。同樣當一個方法的返回值類型為數(shù)值類型時,實際上該方法的返回值為引用類型,此時就需要進行拆箱操作。簡單來說,裝箱就是將數(shù)值類型轉(zhuǎn)換為引用類型,拆箱就是將引用類型轉(zhuǎn)換為數(shù)值類型。接下來通過一個案例來學習裝箱與拆箱操作,具體如下所示。裝箱和拆箱裝箱和拆箱namespaceProgram04{classProgram{staticvoidMain(string[]args){intnum=100;objectobj=num;Console.WriteLine("對象obj的值為{0}",obj);num=(int)obj;Console.WriteLine("變量num的值為{0}",num);Console.ReadKey();}}}將int類型變量num賦值給object類型的變量obj,發(fā)生裝箱操作。將object類型的對象obj賦值給int類型的變量num,發(fā)生拆箱操作。裝箱和拆箱裝箱和拆箱運行結(jié)果,如下圖所示。需要注意的是,裝箱與拆箱過程本質(zhì)上是數(shù)據(jù)存儲在棧與堆之間的變更,如果頻繁的進行裝箱與拆箱操作勢必會影響程序的運算效率,所以建議盡量減少相關操作。思考題簡述繼承的概念。如何隱藏基類的方法?02Sealed關鍵字sealed關鍵字修飾類sealed關鍵字修飾類在C#中,使用sealed關鍵字修飾的類不可以被繼承,也就是不能派生子類,這樣的類通常被稱為密封類。接下來通過一個簡單的例子來演示sealed關鍵字的使用。namespaceProgram05{sealedclassAnimal{publicvoidShout(){Console.WriteLine("動物叫");}}classDog:Animal{publicvoidRun(){Console.WriteLine("狗在跑");}}}sealed關鍵字修飾類sealed關鍵字修飾類程序編譯報錯,如下圖所示。由于Animal類被sealed關鍵字修飾,因此當Dog類繼承Animal類時,編譯器中會出現(xiàn)“Dog”:無法從密封類型“Animal派生”的錯誤。由此可見,被sealed關鍵字修飾的類不能被其他類繼承。sealed關鍵字修飾類sealed關鍵字修飾類當一個類中的方法被sealed關鍵字修飾后,這個類的子類將不能重寫該方法。接下來通過一個案例來演示被sealed關鍵字修飾的方法。sealed關鍵字修飾類sealed關鍵字修飾類namespaceProgram06{......classBlackDog:Dog{publicoverridevoidShout(){Console.WriteLine("黑色狗的叫聲");}}classProgram{staticvoidMain(string[]args){Dogdog=newDog();//創(chuàng)建Dog類對象dog.Shout();Console.ReadKey();}}}namespaceProgram06{classAnimal{publicvirtualvoidShout(){Console.WriteLine("動物的叫聲");}}classDog:Animal{publicsealedoverridevoidShout(){Console.WriteLine("狗的叫聲");}}......}sealed關鍵字修飾類sealed關鍵字修飾類程序編譯報錯,如下圖所示。此時編譯器已報錯,報錯信息為“BlackDog.Shout()”:繼承成員“Dog.Shout()”是密封的,無法進行重寫。說明Dog類中被sealed關鍵字修飾的Shout()方法不能在BlackDog類中被重寫。思考題使用sealed修飾的類和方法有什么特點?03多態(tài)多態(tài)多態(tài)在設計一個方法時,通常希望該方法具備一定的通用性。例如要實現(xiàn)一個動物叫的方法,由于每種動物的叫聲是不同的,因此可以在方法中接收一個動物類型的參數(shù),當傳入貓類對象時就發(fā)出貓類的叫聲,傳入犬類對象時就發(fā)出犬類的叫聲。此時,可以通過多態(tài)的方式來實現(xiàn)這種功能。所謂多態(tài)就是當調(diào)用同一個方法時,由于傳入的參數(shù)類型不同而導致執(zhí)行效果各異的現(xiàn)象。重寫父類方法重寫父類方法在繼承關系中,子類會自動繼承父類中的方法,但有時父類的方法不能滿足子類的需求,那么可以對父類的方法進行重寫。當重寫父類的方法時,要求子類的方法名、參數(shù)類型和參數(shù)個數(shù)必須與父類方法相同,而且父類方法必須使用virtual關鍵字修飾,子類方法必須使用override關鍵字修飾。上一節(jié)案例中,Dog類從Animal類繼承了Shout()方法,該方法在被調(diào)用時會打印“動物叫”。這明顯不能描述一種具體動物的叫聲,Dog類對象表示犬類,發(fā)出的叫聲應該是汪汪。為了解決這個問題,可以在Dog類中重寫父類Animal中的Shout()方法,具體代碼如下所示。重寫父類方法重寫父類方法namespaceProgram07{classAnimal{publicvirtualvoidShout(){Console.WriteLine("動物發(fā)出叫聲");}}classDog:Animal{publicoverridevoidShout(){Console.WriteLine("汪汪......");}}......}使用virtual關鍵字表示可被子類重寫重寫父類的方法重寫父類方法重寫父類方法namespaceProgram07{......classProgram{staticvoidMain(string[]args){Dogdog=newDog();//創(chuàng)建Dog類的實例對象dog.Shout();//調(diào)用dog重寫的shout()方法Console.ReadKey();}}}重寫父類方法重寫父類方法運行結(jié)果如下圖所示。根據(jù)運行結(jié)果可知,在調(diào)用Dog類對象的Shout()方法時,程序只會調(diào)用子類重寫的Shout()方法,并不會調(diào)用父類的Shout()方法。注意:子類重寫父類方法時,不能使用比父類中被重寫的方法更嚴格的訪問權(quán)限,如父類方法的訪問修飾符是public,子類中的方法的修飾符就不能是private。多態(tài)的實現(xiàn)多態(tài)的實現(xiàn)在C#中為了實現(xiàn)多態(tài),允許使用一個父類類型的變量來引用一個子類對象,根據(jù)被引用子類對象特征的不同,得到不同的運行結(jié)果。而實現(xiàn)多態(tài)的方式有多種,接下來通過重寫的方式來演示如何實現(xiàn)多態(tài)。namespaceProgram08{classAnimal{publicvirtualvoidShout(){Console.WriteLine("動物叫......");}}classCat:Animal{publicoverridevoidShout(){Console.WriteLine("喵喵......");}}......}多態(tài)的實現(xiàn)namespaceProgram08{......classDog:Animal{publicoverridevoidShout(){Console.WriteLine("汪汪......");}}classProgram{staticvoidMain(string[]args){Animalan1=newCat();//創(chuàng)建Cat對象,使用Animal類型的變量an1引用Animalan2=newDog();//創(chuàng)建Dog對象,使用Animal類型的變量an2引用animalShout(an1);//調(diào)用animalShout()方法,將an1作為參數(shù)傳入animalShout(an2);//調(diào)用animalShout()方法,將an2作為參數(shù)傳入Console.ReadKey();}publicstaticvoidanimalShout(Animalan){//接收一個Animal類型的參數(shù)an.Shout();//調(diào)用實際參數(shù)的shout()方法}}}多態(tài)的實現(xiàn)多態(tài)的實現(xiàn)多態(tài)的實現(xiàn)運行結(jié)果如下圖所示。上述示例中實現(xiàn)了父類類型變量引用了不同子類的對象,調(diào)用animalShout()方法時,將父類引用的兩個不同子類對象分別傳入,運行結(jié)果中輸出了“喵喵……”與“汪汪……”。由此可見,多態(tài)不僅解決了方法同名的問題,而且還使程序變得更加靈活,從而有效提高程序的可擴展性和可維護性。base關鍵字base關鍵字當子類重寫父類的方法后,子類對象將無法直接訪問父類被重寫的方法。C#中提供了一個base關鍵字專門用于在子類中訪問父類的成員,例如訪問父類的字段、方法和構(gòu)造方法等。接下來分兩種情況來演示base關鍵字的具體用法。1、調(diào)用父類的字段和方法,具體語法格式如下:base.字段名base.方法名([參數(shù)1,參數(shù)2,…])為了讓初學者更好的學習base關鍵字的使用,接下來通過一個案例來演示如何訪問父類的字段和方法,具體代碼如下所示。base關鍵字namespaceProgram09{classAnimal{publicstringname="動物類";publicvirtualvoidShout(){Console.WriteLine("動物的叫聲");}}classDog:Animal{publicoverridevoidShout(){//重寫父類的shout()方法base.Shout();//訪問父類的成員方法}publicvoidPrintName(){//定義打印name的方法Console.WriteLine("name="+);//訪問父類的成員變量}}......}base關鍵字Base訪問父類的方法Base訪問父類的字段base關鍵字base關鍵字運行結(jié)果如下圖所示。由運行結(jié)果可知,子類通過base關鍵字可以成功訪問父類中的字段和方法。base關鍵字base關鍵字2、調(diào)用父類的構(gòu)造方法,具體語法格式如下:classA{//父類}classB:A{//子類publicB():base(){//使用base關鍵字調(diào)用父類默認構(gòu)造方法}}根據(jù)前面的學習可知,繼承關系中,在創(chuàng)建子類的對象時,父類的構(gòu)造方法是默認執(zhí)行的。接下來通過一個案例來演示base關鍵字如何訪問父類的有參構(gòu)造方法,具體代碼如下所示。base關鍵字namespaceProgram10{classAnimal{publicAnimal(){Console.WriteLine("默認構(gòu)造方法");}publicAnimal(stringname){//定義Animal類的有參構(gòu)造方法Console.WriteLine("Animal類的有參構(gòu)造方法被"+name);}}classDog:Animal{publicDog(stringname):base(name){//定義Dog類的有參構(gòu)造方法Console.WriteLine("Dog類的有參構(gòu)造方法被"+name);}}......}base關鍵字Base訪問父類的有參構(gòu)造方法base關鍵字base關鍵字namespaceProgram10{......classProgram{staticvoidMain(string[]args){Dogdog=newDog("執(zhí)行");//實例化子類Console.ReadKey();}}}base關鍵字base關鍵字運行結(jié)果如下圖所示。由運行結(jié)果可知,通過base關鍵字可以調(diào)用父類的構(gòu)造方法。里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則在現(xiàn)實生活中經(jīng)常把某事物看作某類型,例如可以將貓和狗看作動物類型。在程序中也經(jīng)常將子類對象當作父類類型來使用,這時子類與父類之間需要進行類型轉(zhuǎn)換,在轉(zhuǎn)換的過程中需要遵循里氏轉(zhuǎn)換原則。接下來通過兩種情況來說明一下里氏轉(zhuǎn)換原則。1、子類對象可以直接賦值給父類變量,具體代碼如下:Animalan1=newCat();//將Cat類的對象賦值給Animal類的變量Animalan2=newDog();//將Dog類的對象賦值給Animal類的變量上述示例中,Cat類與Dog類都是Animal類的子類,在實例化對象時可以將子類對象賦值給父類變量。里氏轉(zhuǎn)換原則接下來通過一個具體的案例來演示這種情況,具體代碼如下所示。namespaceProgram11{classAnimal{//使用virtual關鍵字使該方法在子類中可被重寫publicvirtualvoidShout(){Console.WriteLine("Animal類中Shout()方法被執(zhí)行");}}classDog:Animal{//使用override關鍵字重寫父類Shout()方法publicoverridevoidShout(){Console.WriteLine("Dog類中的Shout()方法被執(zhí)行");}}......}里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則namespaceProgram11{......classProgram{staticvoidMain(string[]args){Animalanimal=newDog();//子類Dog的實例直接賦值給父類型的變量animal.Shout();//調(diào)用子類Dog重寫的Shout()方法animal=newCat();//子類Cat的實例直接賦值給父類型的變量animal.Shout();//調(diào)用子類Cat重寫的Shout()方法Console.ReadKey();}}}做了一次里氏轉(zhuǎn)換,子類Dog直接賦值給了父類,并通過父類變量調(diào)用了子類的方法做了一次里氏轉(zhuǎn)換,子類Cat直接賦值給了父類,并通過父類變量調(diào)用了子類的方法里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則運行結(jié)果如下圖所示。由運行結(jié)果可知,子類對象可以直接賦值給父類變量,并通過父類變量可以調(diào)用子類中的方法。里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則2、父類對象賦值給子類變量時需要進行強制類型轉(zhuǎn)換在上一個案例的講解中將子類對象賦值給父類變量時,直接賦值即可,但是將父類對象賦值給子類變量時需要進行強制類型轉(zhuǎn)換。例如將Animal類的對象animal賦值給Dog類型變量時,需要在animal對象前面添加括號,括號中指定將父類類型轉(zhuǎn)換為子類類型。接下來通過一個案例來演示將父類對象賦值給子類變量,具體代碼如下所示。里氏轉(zhuǎn)換原則namespaceProgram12{classAnimal{publicvoidShout(){Console.WriteLine("Animal類中Shout()方法被調(diào)用");}}classDog:Animal{publicvoidRun(){Console.WriteLine("Dog類中的Run()方法被調(diào)用");}}......}里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則namespaceProgram12{......classProgram{staticvoidMain(string[]args){Animalanimal=newDog();//子類Dog指向父類Animalanimal.Shout();Dogdog=(Dog)animal;//父類對象animal強制轉(zhuǎn)換為子類類型dog.Run();Console.ReadKey();}}}里氏轉(zhuǎn)換原則父類對象里氏轉(zhuǎn)換為子類,需要將父類對象強制轉(zhuǎn)換為子類類型里氏轉(zhuǎn)換原則里氏轉(zhuǎn)換原則運行結(jié)果如下圖所示。由運行結(jié)果可知,在繼承關系中,當子類對象指向父類變量時,父類變量也可以通過強制類型轉(zhuǎn)換的方式指向子類變量。Object類在C#中提供了一個Object類,它是所有類的父類,也就是每個類都直接或間接繼承自該類,接下來通過一個例子來演示Object類是所有類的父類,具體代碼如下所示。namespaceProgram14{classAnimal{voidShout(){//定義動物叫的方法Console.WriteLine("動物叫");}}classProgram{staticvoidMain(string[]args){Animalanimal=newAnimal();//創(chuàng)建Animal類的對象Console.WriteLine(animal.ToString());//調(diào)用ToString()方法并打印Console.ReadKey();}}}Object類調(diào)用了Object的ToString()方法Object類Object類運行結(jié)果如下圖所示。由運行結(jié)果可知,程序成功的調(diào)用了Animal類中的ToString()方法,雖然Animal類中沒有定義該方法,但是程序并沒有報錯。這是因為Animal類默認繼承自Object類,而Object類中存在ToString()方法,在該方法中輸出了對象的基本信息。Object類在實際開發(fā)中,通常希望對象的ToString()方法返回的不僅僅是基本信息,還有一些特有的信息,此時可以通過重寫Object類的ToString()方法來實現(xiàn)。接下來通過一個案例來演示通過重寫Object類的ToString()方法返回一些特有的信息,具體代碼如下所示。namespaceProgram15{classAnimal{publicoverridestringToString(){//重寫Object類的ToString()方法return"動物叫";}}classProgram{staticvoidMain(string[]args){Animalanimal=newAnimal();//創(chuàng)建Animal對象Console.WriteLine(animal.ToString());//打印animal的ToString()方法的返回值Console.ReadKey();}}}Object類重寫了Object類的ToString()方法Object類Object類運行結(jié)果如下圖所示。由運行結(jié)果可知,通過在Animal類中重寫Object類中的ToString()方法來打印“動物叫”信息。思考題1.方法的重寫需要滿足什么條件?2.可以通過哪些方式實現(xiàn)多態(tài)?04抽象類和接口抽象類和接口抽象類和接口由abstract關鍵字修飾的類為抽象類,抽象類中的方法不用寫方法體,抽象類中可以有抽象方法,也可以有不是抽象的方法。然而接口必須使用interface關鍵字來聲明,接口中的方法都為抽象方法,抽象方法與接口是面向?qū)ο笾斜仨氁獙W習的內(nèi)容。抽象類抽象類當定義一個類時,常常需要定義一些方法來描述該類的行為特征,但有時這些方法的實現(xiàn)方式是無法確定的。例如在前面小節(jié)中定義Animal類時,Shout()方法用于表示動物的叫聲,但是針對不同的動物,叫聲也是不同的,因此在Shout()方法中無法準確地描述具體是哪種動物的叫聲。針對上面描述的情況,C#允許在定義方法時不寫方法體,不包含方法體的方法為抽象方法,抽象方法必須使用abstract關鍵字來修飾,具體示例如下:abstractvoidShout();//定義抽象方法Shout()抽象類抽象類當一個類中包含了抽象方法,該類也必須使用abstract關鍵字來修飾,使用abstract關鍵字修飾的類為抽象類,具體示例如下://定義抽象類AnimalabstractclassAnimal{abstractvoidShout();//定義抽象方法Shout()}需要注意的是,包含抽象方法的類必須聲明為抽象類,但是抽象類可以不包含抽象方法。另外,抽象類是不可以被實例化的,因為抽象類中有可能包含抽象方法,抽象方法是沒有方法體的,不可以被調(diào)用。如果想調(diào)用抽象類中定義的方法,則需要創(chuàng)建一個子類,在子類中實現(xiàn)抽象類中的抽象方法。抽象類抽象類接下來通過一個案例來演示如何實現(xiàn)抽象類中的方法,具體示例如下:namespaceProgram16{abstractclassAnimal{publicabstractvoidShout();//定義抽象方法Shout()}classDog:Animal{//實現(xiàn)抽象方法Shout()publicoverridevoidShout(){Console.WriteLine("汪汪......");}}......}通過override實現(xiàn)了父類的抽象方法抽象類抽象類namespaceProgram16{......classProgram{staticvoidMain(string[]args){Dogdog=newDog();//創(chuàng)建Dog類的實例對象dog.Shout();Console.ReadKey();}}}抽象類抽象類運行結(jié)果如下圖所示。由運行結(jié)果可知,子類Dog通過override關鍵字實現(xiàn)了父類Animal中的抽象方法后,可以進行正常的實例化,并通過實例化對象調(diào)用子類中重寫的Shout()方法。接口接口如果一個抽象類中的所有方法都是抽象的,則可以將這個類用另外一種方式來定義,即接口。在定義接口時,需要使用interface關鍵字來聲明,具體示例如下:interfaceAnimal{voidBreathe();//定義抽象方法voidRun();//定義抽象方法}由于接口中的方法都是抽象方法,因此不能通過實例化對象的方式來調(diào)用接口中的方法。此時需要定義一個類來實現(xiàn)接口中的所有方法。接下來通過一個案例來演示如何調(diào)用接口中的抽象方法,具體示例如下:接口接口namespaceProgram17{interfaceAnimal{voidBreathe();voidRun();}classDog:Animal{//實現(xiàn)Breathe()方法publicvoidBreathe(){Console.WriteLine("狗在呼吸");}//實現(xiàn)Run()方法publicvoidRun(){Console.WriteLine("狗在跑");}}......}接口的實現(xiàn)接口接口namespaceProgram17{......classProgram{staticvoidMain(string[]args){Dogdog=newDog();//創(chuàng)建Dog類的實例對象dog.Breathe();//調(diào)用Dog類的Breathe()方法dog.Run();//調(diào)用Dog類的Run()方法Console.ReadKey();}}}接口接口運行結(jié)果如下圖所示。由運行結(jié)果可知,當調(diào)用Dog類中實現(xiàn)的Animal接口中的方法時,程序便會在控制臺中輸出“狗在呼吸”與“狗在跑”的信息。接口接口為了加深初學者對接口的認識,接下來對接口的特點進行歸納,具體如下:
1.接口中的所有方法都是抽象的,因此接口不能被實例化。
2.一個類可以實現(xiàn)多個接口,被實現(xiàn)的多個接口之間要用逗號隔開,具體示例如下:interfaceRun{程序代碼......}interfaceFly{程序代碼......}classBird:Run,Fly{程序代碼......}接口接口
3.一個接口可以繼承多個接口,接口之間用逗號隔開,具體示例如下:interfaceRunning{程序代碼......}interfaceFlying{程序代碼......}InterfaceEating:Running,Flying{程序代碼......}思考題簡述抽象類和接口的異同點。05異常什么是異常什么是異常異常是錯誤發(fā)生的信號,一旦程序出錯就會產(chǎn)生一個異常,如果該異常沒有被應用程序處理,那么該異常就會被拋出,程序的執(zhí)行也會隨之終止。為了不讓程序終止,我們需要知道什么是異常、如何捕獲異常、如何拋出異常等信息。盡管人人希望自己身體健康,處理的事情都能順利進行,但在實際生活中總會遇到各種狀況,比如感冒發(fā)燒,工作時電腦藍屏、死機等等。程序運行過程中,也會發(fā)生這種非正常狀況,比如程序運行時磁盤空間不足,網(wǎng)絡連接中斷,被操作的文件不存在。針對這種情況,C#程序引入了異常處理機制,通過異常處理機制對程序運行時出現(xiàn)的各種問題進行處理。什么是異常什么是異常接下來通過一個案例來演示什么是異常,具體示例如下:namespaceProgram19{classProgram{staticvoidMain(string[]args){intnum1=10;intnum2=0;intnum3=num1/num2;//除數(shù)為0,將拋出異常Console.WriteLine("num3="+num3);Console.ReadKey();}}}什么是異常什么是異常運行程序時,程序出現(xiàn)異常,具體示例如下:由上圖可知,程序中出現(xiàn)了未處理的異常DivideByZeroException,這個異常就是由除數(shù)為0引起的。什么是異常什么是異常DivideByZeroException異常只是異常類中的一種,C#中提供了大量的異常類,這些類都繼承自Exception類,接下來通過一張圖來展示Exception類的繼承體系,如下圖所示。什么是異常什么是異常為了更好的展示異常信息,每個異常對象中都包含一些只讀屬性,這些屬性可以描述異常的信息,通過這些屬性可以更準確地找到異常出現(xiàn)的原因,異常對象的常用屬性如下表所示。屬性類型描述Messagestring此屬性含有解釋異常原因的消息StackTracestring此屬性含有描述異常發(fā)生在位置信息InnerExceptionException如果當前異常是由另一個異常引起的,此屬性包含前一個異常的引用HelpLinkstring此屬性為異常原因信息提供URN或者URLSourcestring此屬性含有異常起源所在的程序集的名稱try…catch和finallytry…catch和finally如果程序發(fā)生了異常并立即終止,無法繼續(xù)向下執(zhí)行。為了解決這樣的問題,C#程序中提供了一種對異常進行處理的方式——異常捕獲。異常捕獲通常使用try…catch語句,具體語法格式如下:try{//程序代碼塊}catch(ExceptionTypee){//可以是Exception類及其子類//對異常的處理}try…catch和finallytry…catch和finallyC#中的catch代碼塊有多種形式,不同形式的代碼塊用于處理不同級別的異常,具體如下:
1. 一般的catch代碼塊
catch后面沒有任何內(nèi)容,可以匹配try代碼塊中任意類型的異常,具體語法格式如下:catch{//對異常的處理}try…catch和finallytry…catch和finally2.特定catch代碼塊catch后帶有異常類型,它可以匹配該類型的所有異常,具體語法格式如下:
catch(Exceptiontype){//對異常的處理}3.特定對象的catch代碼塊catch后不僅帶有異常類型,還帶有異常對象,通過異常對象可以獲取異常信息,具體語法格式如下:
catch(ExceptiontypeInstID){//對異常的處理}try…catch和finallytry…catch和finally使用try...catch語句對案例中出現(xiàn)的異常進行捕獲,具體代碼如下:
namespaceProgram20{classProgram{staticvoidMain(string[]args){try{......}catch(DivideByZeroExceptione){Console.WriteLine("已處理異常信息:"+e.Message);Console.ReadKey();}catch(SystemException){Console.WriteLine("已處理系統(tǒng)異常");}catch{Console.WriteLine("已處理異常");}}}}try…catch和finallytry…catch和finally運行結(jié)果如下圖所示。由運行結(jié)果可知,當try代碼塊中的代碼拋出異常之后,被第一個catch代碼塊捕獲,并執(zhí)行該代碼塊中的代碼,異常不再被拋出。在程序中,如果希望有些語句在程序無論是否發(fā)生異常都要執(zhí)行,此時就可以在try…catch語句后
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度養(yǎng)殖場廢棄物資源化利用技術(shù)承包合同范本4篇
- 2022版義務教育階段英語課程標準模擬測試卷
- 2025年度整棟醫(yī)療設施出租經(jīng)營合同4篇
- 2025年度存量房交易資金監(jiān)管服務合同范本2篇
- 2024智能健康監(jiān)測設備研發(fā)與生產(chǎn)合同
- 2025別墅庭院園藝景觀植物租賃與養(yǎng)護合同3篇
- 2025年度新能源汽車動力電池回收利用技術(shù)合作合同范本3篇
- 2024美容院員工勞動合同及保密協(xié)議
- 2025年度醫(yī)院兒科病房改造與承包運營協(xié)議4篇
- 2025年度床上用品行業(yè)環(huán)保公益活動合作合同3篇
- 納米復合材料增強金屬基材
- 拆除豬場補償協(xié)議書模板
- 水利水電工程施工安全管理導則
- 5歲幼兒數(shù)學練習題
- 2024年高中生物新教材同步選擇性必修第三冊學習筆記第3章 本章知識網(wǎng)絡
- 2024年全國體育單招英語考卷和答案
- 食品安全管理制度可打印【7】
- 藥物流行病學教學大綱
- 健康管理師二級理論考核試題及答案
- 手術(shù)室常見消毒滅菌方法
- 2024年九年級語文中考名著閱讀《儒林外史》考前練附答案
評論
0/150
提交評論