第4章 面向?qū)ο缶幊踢M(jìn)階.ppt_第1頁(yè)
第4章 面向?qū)ο缶幊踢M(jìn)階.ppt_第2頁(yè)
第4章 面向?qū)ο缶幊踢M(jìn)階.ppt_第3頁(yè)
第4章 面向?qū)ο缶幊踢M(jìn)階.ppt_第4頁(yè)
第4章 面向?qū)ο缶幊踢M(jìn)階.ppt_第5頁(yè)
已閱讀5頁(yè),還剩135頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第4章 面向?qū)ο缶幊踢M(jìn)階,4.1類(lèi)的繼承與多態(tài) 當(dāng)今的面向?qū)ο缶幊陶Z(yǔ)言都提供了繼承和多態(tài)的功能,C#作為一種面向?qū)ο蟮母呒?jí)編程語(yǔ)言也具有這樣的特點(diǎn)。繼承是面向?qū)ο笳Z(yǔ)言的基本特征,是實(shí)現(xiàn)代碼復(fù)用的手段。繼承使得在原有的類(lèi)基礎(chǔ)之上,對(duì)原有的程序進(jìn)行擴(kuò)展,從而提高程序開(kāi)發(fā)的速度,實(shí)現(xiàn)代碼的復(fù)用。同一種方法作用于不同對(duì)象可以產(chǎn)生不同的結(jié)果,這就是多態(tài)性。它是在基類(lèi)中使用虛方法,在其派生類(lèi)中使用重載實(shí)現(xiàn)的。,4.1.1 繼承,1. 使用繼承 繼承是指這樣一種能力:它可以使用現(xiàn)有類(lèi)的所有功能,并在無(wú)需重新編寫(xiě)原來(lái)的類(lèi)的情況下對(duì)這些功能進(jìn)行擴(kuò)展。使用繼承而產(chǎn)生的類(lèi)被稱(chēng)為派生類(lèi)或者子類(lèi),而被繼承的類(lèi)則稱(chēng)為基類(lèi)

2、、超類(lèi)或父類(lèi)??陀^世界中的許多事物之間往往都是具有相同的特征,具有繼承的特點(diǎn)。圖4.1和圖4.2是兩個(gè)采用類(lèi)的層次圖表示繼承的例子。,1. 使用繼承,圖4.1 類(lèi)的層次結(jié)構(gòu)1,圖4.2 類(lèi)的層次結(jié)構(gòu)2,4.1.1 繼承,【例4.1】類(lèi)的繼承。 using System; /定義基類(lèi)Shape public class Shape protected string Color; public Shape() ; public Shape(string Color) this.Color = Color; public string GetColor() return Color; ,【例4.1】

3、,/定義Circle類(lèi),從Shape類(lèi)中派生 public class Circle : Shape private double Radius; public Circle(string Color, double Radius) this.Color = Color; this.Radius = Radius; public double GetArea() return System.Math.PI * Radius * Radius; ,【例4.1】,/ 派生類(lèi)Rectangular,從Shape類(lèi)中派生 public class Rectangular:Shape protected

4、 double Length, Width; public Rectangular() Length=Width=0; public Rectangular(string Color,double Length, double Width) this.Color = Color; this.Length = Length; this.Width = Width; public double AreaIs() return Length*Width; ,【例4.1】,public double PerimeterIs()/周長(zhǎng) return (2*(Length+Width); / 派生類(lèi)Squ

5、are,從 Rectangular類(lèi)中派生 public class Square: Rectangular public Square(string Color,double Side) this.Color = Color; this.Length=this.Width = Side; public class TestInheritance public static void Main(),【例4.1】, Circle Cir= new Circle(orange,3.0); Console.WriteLine(Circle color is 0,Circle area is 1, C

6、ir.GetColor(),Cir.GetArea(); Rectangular Rect= new Rectangular(red,13.0, 2.0); Console.WriteLine(Rectangualr color is 0,Rectangualr area is 1, Rectangular perimeter is 2, Rect.GetColor(),Rect.AreaIs(), Rect.PerimeterIs(); Square Squ= new Square(green,5.0); Console.WriteLine(Square color is 0,Square

7、Area is 1, Square perimeter is 2, Squ.GetColor(),Squ.AreaIs(), Squ.PerimeterIs(); 運(yùn)行結(jié)果如圖4.3所示。,圖4.3 運(yùn)行結(jié)果,4.1.1 繼承,2. base關(guān)鍵字 例4.1程序中的square類(lèi)也可以改寫(xiě)為: / 派生類(lèi)Square,從 Rectangular類(lèi)中派生 public class Square: Rectangular public Square(string Color,double Side):base(Color,Side,Side) ; 關(guān)鍵字base的作用是調(diào)用Rectangular類(lèi)

8、的構(gòu)造函數(shù)并將Square類(lèi)的變量初始化。如果將Square類(lèi)改寫(xiě)成: / 派生類(lèi)Square,從 Rectangular類(lèi)中派生 public class Square: Rectangular public Square(string Color,double Side) ; ,2. base關(guān)鍵字,實(shí)際上這種情況調(diào)用的是父類(lèi)的無(wú)參構(gòu)造函數(shù),而不是有參構(gòu)造函數(shù),等同于: / 派生類(lèi)Square,從 Rectangular類(lèi)中派生 public class Square: Rectangular public Square(string Color,double Side):base() ;

9、 base關(guān)鍵字除了能調(diào)用基類(lèi)對(duì)象構(gòu)造函數(shù),還可以調(diào)用基類(lèi)的方法。在下例中,Employee類(lèi)的GetInfoEmployee方法使用了base關(guān)鍵字調(diào)用基類(lèi)Person的GetInfoPerson方法。,2. base關(guān)鍵字,【例4.2】base調(diào)用基類(lèi)的方法。 using System; public class Person protected string Phone = 444-555-666; protected string Name = 李明; public void GetInfoPerson() Console.WriteLine(Phone: 0, Phone); Con

10、sole.WriteLine(Name: 0, Name); class Employee : Person public string ID = ABC567EFG; public void GetInfoEmployee(),【例4.2】, / 調(diào)用基類(lèi)Person的GetInfo方法 base.GetInfoPerson(); Console.WriteLine(Employee ID: 0,ID); class TestClass public static void Main() Employee Employees = new Employee(); Employees.GetIn

11、foEmployee(); ,4.1.1 繼承,3. 繼承中的構(gòu)造函數(shù)與析構(gòu)函數(shù) 在前面討論過(guò)派生類(lèi)的構(gòu)造函數(shù)會(huì)隱式調(diào)用父類(lèi)的無(wú)參構(gòu)造函數(shù)。那么,如果父類(lèi)也是派生于其它類(lèi),會(huì)是什么樣的情形呢?C#的執(zhí)行順序是這樣的:根據(jù)層次鏈找到最頂層的基類(lèi),先調(diào)用基類(lèi)的構(gòu)造函數(shù),再依次調(diào)用各級(jí)派生類(lèi)的構(gòu)造函數(shù)。而析構(gòu)函數(shù)的次序正好相反。 【例4.3】繼承中的構(gòu)造函數(shù)與析構(gòu)函數(shù)。 using System; public class BaseLifeSample public static void Main() Son s1 = new Son(); public class Grandsire,【例4.3

12、】, public Grandsire() Console.WriteLine(調(diào)用Grandsire的構(gòu)造函數(shù)); Grandsire() Console.WriteLine(調(diào)用Grandsire的析構(gòu)函數(shù)); public class Father : Grandsire public Father() Console.WriteLine(調(diào)用Father的構(gòu)造函數(shù)); Father() Console.WriteLine(調(diào)用Father的析構(gòu)函數(shù)); ,【例4.3】,public class Son : Father public Son() Console.WriteLine(調(diào)用

13、Son的構(gòu)造函數(shù)); Son() Console.WriteLine(調(diào)用Son的析構(gòu)函數(shù)); 運(yùn)行結(jié)果如圖4.4所示。,圖4.4 運(yùn)行結(jié)果,4.1.1 繼承,4. System.Object類(lèi) C#所有類(lèi)都派生于System.Object類(lèi)。在定義類(lèi)時(shí)如果沒(méi)有指定派生于哪一個(gè)類(lèi),系統(tǒng)就默認(rèn)其派生于Object類(lèi)。例4.2中Shape的定義就等同于: public class Shape :System.Object System.Object類(lèi)常見(jiàn)的公有方法是: Equals:如果兩個(gè)對(duì)象具有相同值時(shí),方法將返回true。 GetHashCode:方法返回對(duì)象的值的散列碼。 ToString

14、:通過(guò)在派生類(lèi)中重寫(xiě)該方法,返回一個(gè)表示對(duì)象狀態(tài)的字符串。,4.1.2多態(tài),多態(tài)也是面向?qū)ο笳Z(yǔ)言的基本特征之一,是指在程序執(zhí)行之前無(wú)法根據(jù)函數(shù)名和參數(shù)確定調(diào)用哪一個(gè)操作,而是程序執(zhí)行過(guò)程中,根據(jù)實(shí)際運(yùn)行情況動(dòng)態(tài)確定,從而帶來(lái)編程高度的靈活性。實(shí)現(xiàn)多態(tài)的方法是使用虛方法。 1. 虛方法的重載 在類(lèi)的方法前加上關(guān)鍵字virtual, 則該方法被稱(chēng)為虛方法。通過(guò)對(duì)虛方法的重載,實(shí)現(xiàn)在程序運(yùn)行過(guò)程中確定調(diào)用的方法。需要注意的是這里所講的重載與第3章所講的通過(guò)參數(shù)類(lèi)型與參數(shù)個(gè)數(shù)的不同實(shí)現(xiàn)的重載含義是不同的。 【例4.4】虛方法的重載。 using System; class A public void

15、F() Console.WriteLine(A.F); public virtual void G() Console.WriteLine(A.G); ,【例4.4】,class B: A new public void F() Console.WriteLine(B.F); public override void G() Console.WriteLine(B.G); class Test static void Main() B b = new B(); A a = b; a.F(); b.F(); a.G(); b.G(); ,【例4.4】,在A 類(lèi)定義了提供了非虛的F和虛方法 G,

16、派生類(lèi)B 則對(duì)方法F實(shí)現(xiàn)覆蓋,對(duì)虛方法G 實(shí)現(xiàn)了虛方法的的重載?!癆 a = b”實(shí)際上a仍舊是一個(gè)b對(duì)象。輸出結(jié)果為: A.F B.F B.G B.G 在例4.1中計(jì)算圓形和矩形的面積分用了兩個(gè)不同的方法GetArea和AreaIs,也可以通過(guò) 虛方法實(shí)現(xiàn)。將Shape中增加虛方法: public virtual double GetArea() return 0.0; 在Circle類(lèi)中對(duì)虛方法重載: public override double GetArea() return System.Math.PI * radius * radius; 在Rectangular類(lèi)中對(duì)虛方法重載:

17、 public override double GetArea() return Length*Width; ,4.1.2多態(tài),【例4.5】用虛方法的實(shí)現(xiàn)重載 using System; /定義基類(lèi)Shape public class Shape protected string Color; public Shape() ; public Shape(string Color) this.Color = Color; public string GetColor() return Color; public virtual double GetArea() return 0.0; ,【例4.

18、5】,/定義Circle類(lèi),從Shape類(lèi)中派生 public class Circle : Shape private double Radius; public Circle(string Color, double Radius) this.Color = Color; this.Radius = Radius; public override double GetArea() return System.Math.PI * Radius * Radius; / 派生類(lèi)Rectangular,從Shape類(lèi)中派生 public class Rectangular:Shape,【例4.5】

19、, protected double Length, Width; public Rectangular(string Color,double Length, double Width) this.Color = Color; this.Length = Length; this.Width = Width; public override double GetArea() return Length*Width; public double PerimeterIs() / 周長(zhǎng) return (2*(Length+Width); ,【例4.5】,/ 派生類(lèi)Square,從 Rectangu

20、lar類(lèi)中派生 public class Square: Rectangular public Square(string Color,double Side):base(Color,Side,Side) ; public class TestInheritance public static void Main() Circle Cir= new Circle(orange,3.0); Console.WriteLine(Circle color is 0,Circle area is 1, Cir.GetColor(),Cir.GetArea(); Rectangular Rect= ne

21、w Rectangular(red,13.0, 2.0); Console.WriteLine(Rectangualr color is 0,Rectangualr area is 1, Rectangular perimeter is,【例4.5】,2, Rect.GetColor(),Rect.GetArea(), Rect.PerimeterIs(); Square Squ= new Square(green,5.0); Console.WriteLine(Square color is 0,Square Area is 1, Square perimeter is 2, Squ.Get

22、Color(),Squ.GetArea(), Squ.PerimeterIs(); Shape Shp= Cir; Console.WriteLine(Circle area is 0, Shp.GetArea(); Shp = Rect; Console.WriteLine(Rectangualr area is 0,Shp.GetArea(); ,4.1.2多態(tài),2. 抽象類(lèi)與抽象方法 抽象類(lèi)是一種特殊的基類(lèi),并不與具體的事物聯(lián)系。抽象類(lèi)的定義使用關(guān)鍵字abstract。在 圖4.2 類(lèi)的層次結(jié)構(gòu)中,并沒(méi)有“圖形”這樣具體事物,所以可以將“圖形”定義為抽象類(lèi),派 生了“圓形”和“四邊形”這

23、樣一些可以產(chǎn)生具體實(shí)例化的普通類(lèi)。需要注意的是,抽象類(lèi)是不 能被實(shí)例化,它只能作為其它類(lèi)的基類(lèi)。將Shape類(lèi)定義為抽象類(lèi): public abstract class Shape 在抽象類(lèi)中也可以使用關(guān)鍵字abstract定義抽象方法,要求所有的派生非抽象類(lèi)都要重載實(shí) 現(xiàn)抽象方法。引入抽象方法的原因在于抽象類(lèi)本身是一種抽象的概念,有的方法并不要具 體的實(shí)現(xiàn),而是留下來(lái)讓派生類(lèi)來(lái)重載實(shí)現(xiàn)。Shape類(lèi)中GetArea方法本身沒(méi)什么具體的 意義,而只有到了派生類(lèi)Circle類(lèi)和Rectangular才可以計(jì)算具體的面積。 抽象方法寫(xiě)法: public abstract double GetAre

24、a(); 則派生類(lèi)重載實(shí)現(xiàn)為: public override double GetArea() ,4.1.2多態(tài),【例4.6】抽象類(lèi)和抽象方法的實(shí)現(xiàn) using System; /定義基類(lèi)Shape public abstract class Shape protected string Color; public Shape() ; public Shape(string Color) this.Color = Color; public string GetColor() return Color; public abstract double GetArea(); ,【例4.6】,/

25、定義Circle類(lèi),從Shape類(lèi)中派生 public class Circle : Shape private double Radius; public Circle(string Color, double Radius) this.Color = Color; this.Radius = Radius; public override double GetArea() return System.Math.PI * Radius * Radius; ,【例4.6】,/ 派生類(lèi)Rectangular, 從Shape類(lèi)中派生 public class Rectangular:Shape p

26、rotected double Length, Width; public Rectangular(string Color,double Length, double Width) this.Color = Color; this.Length = Length; this.Width = Width; public override double GetArea() return Length*Width; public double PerimeterIs() /周長(zhǎng) return (2*(Length+Width); ,【例4.6】,/ 派生類(lèi)Square, 從 Rectangular

27、類(lèi)中派生 public class Square: Rectangular public Square(string Color,double Side):base(Color,Side,Side) ; public class TestInheritance public static void Main() Circle Cir= new Circle(orange,3.0); Console.WriteLine(Circle color is 0,Circle area is 1, Cir.GetColor(),Cir.GetArea(); Rectangular Rect= new R

28、ectangular(red,13.0, 2.0);,【例4.6】,Console.WriteLine(Rectangualr color is 0,Rectangualr area is 1, Rectangular perimeter is 2, Rect.GetColor(),Rect.GetArea(), Rect.PerimeterIs(); Square Squ= new Square(green,5.0); Console.WriteLine(Square color is 0,Square Area is 1, Square perimeter is 2, Squ.GetCol

29、or(),Squ.GetArea(), Squ.PerimeterIs(); ,4.1.2多態(tài),3. 密封類(lèi)和密封方法 抽象類(lèi)是作為基類(lèi),不能被實(shí)例化,由其它類(lèi)繼承。相對(duì)應(yīng)的還有一種不能被其它類(lèi)繼承 的類(lèi),叫密封類(lèi),使用sealed關(guān)鍵字定義。如果Rectangular類(lèi)定義為密封類(lèi) : public class rectangular:Shape 這樣Rectangular類(lèi)的派生類(lèi)Square就不再保留,否則,就會(huì)出錯(cuò)。 如果類(lèi)的方法聲明包含 sealed 修飾符,稱(chēng)該方法為密封方法。類(lèi)的實(shí)例方法聲明包含 sealed 修飾符,則必須同時(shí)使用override修飾符。使用密封方法可以防止派生

30、類(lèi)進(jìn)一步重 寫(xiě)該方法。如果將圓形Circle類(lèi)的GetArea方法定義為密封類(lèi),必須先將Shape類(lèi)GetArea 方法定義為: public virtual double GetArea() 然后在Circle類(lèi)中實(shí)現(xiàn)密封方法: public sealed override double GetArea() ,4.2 操作符重載,如果有一個(gè)復(fù)數(shù)Complex類(lèi)對(duì)一元操作符“+”重載,可以寫(xiě)成: public static Complex operator +(Complex a) 對(duì)二元操作符“+”可以寫(xiě)成: public static Complex operator +(Complex

31、a, Complex b) ,4.2 操作符重載,一元操作符有一個(gè)參數(shù),二元操作符有二個(gè)參數(shù)。重載操作符開(kāi)始必須以public static修飾??梢灾剌d的操作符包括: 一元操作符:+ - ! + - true false 二元操作符:+ - * / % return x.Sidey.Side; / 重載” ”操作符 public static bool operator (Square x,Square y) Console.WriteLine(重載操作符,兩個(gè)參數(shù)都為square類(lèi)); return x.Sidey.Side; / 重載” = ”操作符 public static bool

32、 operator =(Square x,Square y) Console.WriteLine(重載=操作符,兩個(gè)參數(shù)都為square類(lèi)); return (x=(Square x,Square y) Console.WriteLine(重載=操作符,兩個(gè)參數(shù)都為square類(lèi)); return (xy) | (x=y); /調(diào)用重載的操作符” =”和” ” public static void Main() Square s1=new Square(10); Square s2=new Square(20); Square s3=s1+s2; / 調(diào)用operator + (Square,

33、Square) Console.WriteLine(s3); / 調(diào)用重寫(xiě)object類(lèi)的ToString()方法 Console.WriteLine(s3+15); / 調(diào)用重寫(xiě)的operator + (Square,int)以及ToString() Console.WriteLine(s3+1.5); / 調(diào)用重寫(xiě)的operator + (Square,double)和ToString() s3=10; / 調(diào)用隱式轉(zhuǎn)換public static implicit operator Square(int ) Console.WriteLine(s3); Square s4=10;,【例4.

34、8】,Console.WriteLine(s1=s4); / 調(diào)用= 操作符 Console.WriteLine(s1!=s4); / 調(diào)用 != 操作符 Console.WriteLine(s1s2); / 調(diào)用 操作符 Console.WriteLine(s1=s4); / 調(diào)用=操作符 運(yùn)行結(jié)果如圖4.6所示。 Square與double 和int 之間有兩個(gè)隱式轉(zhuǎn)換。從double以及int隱式轉(zhuǎn)換過(guò)程 不會(huì)丟失數(shù)據(jù)而出現(xiàn)異常,所以采用了隱式轉(zhuǎn)換。 Square類(lèi)默認(rèn)的基類(lèi)是Object類(lèi),所以可以重載Object類(lèi)的方法ToString。 WriteLine方法默認(rèn)的參數(shù)為Strin

35、g對(duì)象,所以在輸出之前都要調(diào)用ToString方 法,將參數(shù)轉(zhuǎn)換為String類(lèi)型。,【例4.8】,圖4.6 運(yùn)行結(jié)果,4.3 類(lèi)型轉(zhuǎn)換,實(shí)際編程中,經(jīng)常用到類(lèi)型的相互之間轉(zhuǎn)換問(wèn)題,如一個(gè)int類(lèi)型要轉(zhuǎn)換成一個(gè)long類(lèi)型。類(lèi)型轉(zhuǎn)換方法分為隱式類(lèi)型轉(zhuǎn)換和顯式類(lèi)型轉(zhuǎn)換,也可以采用Convert提供的方法實(shí)現(xiàn)類(lèi)型轉(zhuǎn)換。 4.3.1 隱式類(lèi)型轉(zhuǎn)換 隱式類(lèi)型轉(zhuǎn)換不需要加任何聲明就可以實(shí)現(xiàn)的類(lèi)型轉(zhuǎn)換,規(guī)則簡(jiǎn)單。 1. 隱式數(shù)值轉(zhuǎn)換 數(shù)值轉(zhuǎn)換是指在整數(shù)類(lèi)型、實(shí)數(shù)類(lèi)型和字符類(lèi)型之間的轉(zhuǎn)換。sbyte類(lèi)型向int類(lèi)型轉(zhuǎn)換是一種隱式數(shù)值類(lèi)型轉(zhuǎn)換,轉(zhuǎn)換一般不會(huì)失敗,也不會(huì)丟失數(shù)據(jù)。如: sbyte a = 100

36、; int b = a; 隱式數(shù)值類(lèi)型轉(zhuǎn)換如表4.1所示。 從int到long,long到float、double等幾種類(lèi)型轉(zhuǎn)換時(shí)可能導(dǎo)致精度的下降,但不導(dǎo)致數(shù)量上的丟失。從表4.1中可以看出,任何的原始類(lèi)型,如果值的范圍完全包含在其它類(lèi)型的值范圍內(nèi),那么就能進(jìn)行隱式轉(zhuǎn)換。需要注意的是char類(lèi)型可以轉(zhuǎn)換為其它的整數(shù)或?qū)崝?shù)類(lèi)型,但不存在其它類(lèi)型轉(zhuǎn)換為char類(lèi)型。,1. 隱式數(shù)值轉(zhuǎn)換,表4.1 隱式數(shù)值類(lèi)型轉(zhuǎn)換,1. 隱式數(shù)值轉(zhuǎn)換,【例4.9】隱式數(shù)值轉(zhuǎn)換。 using System; class ReferenceConversion static void Main() char a =

37、m; int b = a; Console.WriteLine(a equals:0,a); Console.WriteLine(b equals:0,b); 運(yùn)行結(jié)果如下: a equals:m b equals:107 如果這樣寫(xiě): int b = 7; char a = b; Console.WriteLine(a equals:0,a); Console.WriteLine(b equals:0,b); 編譯器將報(bào)錯(cuò):無(wú)法將類(lèi)型“int”隱式轉(zhuǎn)換為“char”。,4.3.1 隱式類(lèi)型轉(zhuǎn)換,2. 隱式枚舉轉(zhuǎn)換 隱式枚舉轉(zhuǎn)換只允許將十進(jìn)制0轉(zhuǎn)換為枚舉類(lèi)型的變量。 【例4.10】隱式枚舉轉(zhuǎn)換

38、。 using System; enum Color Red,Green,Blue class EnumConversion static void Main() Color a = Color.Red; Console.WriteLine(a equals:0,a); a = 0; Console.WriteLine(a equals:0,a); 如果寫(xiě)a = 1或其它數(shù)值,編譯器提示:無(wú)法將類(lèi)型“int”隱式轉(zhuǎn)換為“Color”。,4.3.1 隱式類(lèi)型轉(zhuǎn)換,3. 隱式引用轉(zhuǎn)換 類(lèi)型s向類(lèi)型t隱式引用轉(zhuǎn)換的條件是:s是從t派生來(lái)的,且s和t可以是接口或類(lèi)。兩個(gè)數(shù)組的之間的隱式轉(zhuǎn)換的條件是:兩

39、個(gè)數(shù)組的維數(shù)相同,元素都是引用類(lèi)型,且存在數(shù)組元素的隱式引用轉(zhuǎn)換。例如: class Employee / 隱含繼承自System.Object class App Employee e; object o = e; 使用隱式轉(zhuǎn)換的因?yàn)樵谟贓mployee是派生自O(shè)bject類(lèi)。,4.3.2 顯式類(lèi)型轉(zhuǎn)換,顯式類(lèi)型轉(zhuǎn)換只有在某些情況下實(shí)現(xiàn)轉(zhuǎn)換,規(guī)則復(fù)雜,需要用戶(hù)正確指定要轉(zhuǎn)換的類(lèi)型。又稱(chēng)強(qiáng)制類(lèi)型轉(zhuǎn)換。 1. 顯式數(shù)值轉(zhuǎn)換 int類(lèi)型向byte類(lèi)型轉(zhuǎn)換就是一種顯式數(shù)值類(lèi)型轉(zhuǎn)換。 例如: int b = 100; sbyte a =(byte)b; sbyte取值范圍是0255,當(dāng)int b顯式轉(zhuǎn)

40、換為sbyte時(shí)不會(huì)丟失信息。 int b = 1000; sbyte a =(byte)b; 則會(huì)出信息丟失,這是顯式數(shù)值轉(zhuǎn)換過(guò)程要注意的。 顯式數(shù)值類(lèi)型可轉(zhuǎn)換的類(lèi)型如表4.2。,1. 顯式數(shù)值轉(zhuǎn)換,表4.2 顯式數(shù)值類(lèi)型轉(zhuǎn)換,4.3.2 顯式類(lèi)型轉(zhuǎn)換,2. 顯式枚舉轉(zhuǎn)換 顯式枚舉轉(zhuǎn)換包括幾種情況:從 sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal類(lèi)型到任何枚舉類(lèi)型;從任何枚舉類(lèi)型到 sbyte, byte, short, ushort, int, uint, long, ulo

41、ng, char, float,double, decimal;從任何枚舉類(lèi)型到任何其它枚舉類(lèi)型。顯式枚舉轉(zhuǎn)換其本質(zhì)是枚舉類(lèi)型的元素類(lèi)型與要轉(zhuǎn)換的類(lèi)型之間的顯式轉(zhuǎn)換。 【例4.11】顯式枚舉轉(zhuǎn)換。 using System; enum Color Red, Green = 10, Blue class Test static void Main(),【例4.11】, Console.WriteLine(StringFromColor(Color.Red); Console.WriteLine(StringFromColor(Color.Green); Console.WriteLine(Str

42、ingFromColor(Color.Blue); / 枚舉類(lèi)型向整數(shù)類(lèi)型顯式轉(zhuǎn)換 static string StringFromColor(Color c) switch (c) case Color.Red: / 將指定的String中的每個(gè)格式項(xiàng)替換為相應(yīng)對(duì)象的 值的文本等效項(xiàng)。 return String.Format(Red = 0, (int) c); case Color.Green: return String.Format(Green = 0, (int) c); case Color.Blue: return String.Format(Blue = 0, (int) c

43、);,【例4.11】,default: return Invalid color; 運(yùn)行結(jié)果如下: Red = 0 Green = 10 Blue = 11,4.3.2 顯式類(lèi)型轉(zhuǎn)換,3. 顯式引用轉(zhuǎn)換 類(lèi)型s向類(lèi)型t顯式引用轉(zhuǎn)換的條件是t是從s派生來(lái)的,且s和t可以是接口或類(lèi)。兩個(gè)數(shù)組的之間的隱式轉(zhuǎn)換的條件是兩個(gè)數(shù)組的維數(shù)相同,元素都是引用類(lèi)型,且存在數(shù)組元素的顯式引用轉(zhuǎn)換。 例如: class Employee / 隱含繼承自System.Object class App object o Employee e = (Employee)o; ,4.3.3 使用Convert轉(zhuǎn)換,Syste

44、m.Convert類(lèi)中有一套的靜態(tài)方法實(shí)現(xiàn)類(lèi)型的轉(zhuǎn)換,即使要轉(zhuǎn)換的類(lèi)型之間沒(méi)有什么聯(lián)系也可以很方便的實(shí)現(xiàn)類(lèi)型的轉(zhuǎn)換。包括的方法列在表4.3中。,表4.3 Convert類(lèi)轉(zhuǎn)換的方法,4.3.3 使用Convert轉(zhuǎn)換,【例4.12】System.Convert實(shí)現(xiàn)類(lèi)型轉(zhuǎn)換。 using System; class TestConvert static void Main() short a; try Console.WriteLine(Enter a string:); a = Convert.ToInt16(Console.ReadLine(); Console.WriteLine(a eq

45、uals:0,a); catch (FormatException) Console.WriteLine(字符串不是由數(shù)字組成或?yàn)榭?); catch (OverflowException) Console.WriteLine(字符串的數(shù)值超出了short 范圍.); ,4.4 結(jié)構(gòu)與接口,4.4.1 結(jié)構(gòu) C#中的結(jié)構(gòu)除了包含有數(shù)據(jù)成員,還有構(gòu)造函數(shù)、方法、屬性、事件、索引等成員,結(jié)構(gòu)也可以實(shí)現(xiàn)多個(gè)接口。結(jié)構(gòu)與類(lèi)很類(lèi)似,但也有很多的區(qū)別。首先結(jié)構(gòu)是值類(lèi)型,而類(lèi)是引用類(lèi)型。 【例4.13】值類(lèi)型的結(jié)構(gòu)。 using System; / 定義結(jié)構(gòu) MyStruct struct MyStruct

46、 / 定義字段x,y public int x; public int y; / 定義構(gòu)造函數(shù) public MyStruct(int i, int j) x = i; y = j; ,【例4.13】,/ 定義方法 public void Sum() int sum = x + y; Console.WriteLine(The sum is 0,sum); class Class1 static void Main() MyStruct s1 = new MyStruct(1,2); MyStruct s2 = s1; s1.x = 2; s1.Sum(); s2.Sum(); ,【例4.13

47、】,運(yùn)行結(jié)果如下: The sum is 4 The sum is 3 程序中的s2獲得了s1的數(shù)據(jù)一份拷貝,雖然s1.x值改變了,但并沒(méi)有影響到s2。當(dāng)兩個(gè)類(lèi) 的實(shí)例相等時(shí),則表示它們指向同一段的內(nèi)存地址,試圖改變一個(gè)必然要影響到另一個(gè)。 結(jié)構(gòu)實(shí)例化時(shí)也可以不用new。例如,Class1也可以寫(xiě)成: class Class1 static void Main() MyStruct s1; s1.x = 1; s1.y = 2; MyStruct s2 = s1; s1.x = 2; s1.Sum(); s2.Sum(); ,【例4.13】,如果在Main()加入: MyStruct s3 =

48、 new MyStruct(); s3.Sum(); 雖然結(jié)構(gòu)中沒(méi)有默認(rèn)的無(wú)參構(gòu)造函數(shù),但是卻可以調(diào)用無(wú)參構(gòu)造函數(shù),并且將值類(lèi)型的數(shù)據(jù)成員設(shè)置為對(duì)應(yīng)值類(lèi)型的缺省值,將其引用類(lèi)型的數(shù)據(jù)成員設(shè)置為null。所以s3.x和s3.y都為0,s3最終的和也為0。 結(jié)構(gòu)與類(lèi)的區(qū)別如表4.4所示。,表4.4 結(jié)構(gòu)與類(lèi)的區(qū)別,4.4.2接口,1. 接口介紹 接口是用來(lái)定義一種程序的協(xié)定。接口好比一種模版,這種模版定義了實(shí)現(xiàn)接口的對(duì)象必須實(shí)現(xiàn)的方法,其目的就是讓這些方法可以作為接口實(shí)例被引用。接口的定義如: public interface IPartA void SetDataA(string dataA);

49、 接口使用關(guān)鍵字interface定義,接口可以使用的修飾符包括new,public,protected,internal,private等。接口的命名通常是以I開(kāi)頭,如IPartA,IPartB。接口的成員可以是方法、屬性、索引器和事件,但不可以有任何的成員變量,也不能在接口中實(shí)現(xiàn)接口成員。接口不能被實(shí)例化。接口的成員默認(rèn)是公共的,因此不允許成員加上修飾符。,4.4.2接口,【例4.14】接口演示。 using System; / 定義接口IPartA public interface IPartA void SetDataA(string dataA); / 定義接口IPartB,繼承IP

50、artA public interface IPartB:IPartA void SetDataB(string dataB); / 定義類(lèi)SharedClass,繼承接口IPartB public class SharedClass :IPartB private string DataA; private string DataB;,【例4.14】,/ 實(shí)現(xiàn)接口IPartA的方法SetDataA public void SetDataA(string dataA) DataA=dataA; Console.WriteLine(0,DataA); / 實(shí)現(xiàn)接口IPartB的方法SetData

51、B public void SetDataB(string dataB) DataB=dataB; Console.WriteLine(0,DataB); ,【例4.14】,class test static void Main() SharedClass a = new SharedClass(); a.SetDataA(interface IPartA); a.SetDataB(interface IPartB); 運(yùn)行結(jié)果如下: interface IPartA interface IPartB 程序中一共定義兩個(gè)接口和一個(gè)類(lèi)。接口IPartA定義方法SetDataA,接口IPartB定

52、義方法SetDataB。接口之間也有繼承關(guān)系,接口IPartB繼承接口IPartA,也就繼承了接口IPartA的SetDataA方法。接口只能定義方法,實(shí)現(xiàn)要由類(lèi)或者結(jié)構(gòu)來(lái)完成。SharedClass類(lèi)派生于接口IPartB,因此要實(shí)現(xiàn)IPartB的SetDataB方法,也要實(shí)現(xiàn)IPartA的SetDataA方法。,4.4.2接口,接口允許多重繼承: interface ID:IA,IB,IC 類(lèi)可以同時(shí)有一個(gè)基類(lèi)和零個(gè)以上的接口,并要將基類(lèi)寫(xiě)在前面: class ClassB:ClassA,IA,IB ,4.4.2接口,2. 接口的實(shí)現(xiàn) 指出接口成員所在的接口,則稱(chēng)為顯式接口成員。上面程序接

53、口實(shí)現(xiàn)可改寫(xiě)成: / 沒(méi)有定義為public void IPartA. SetDataA(string dataA) DataA=dataA; Console.WriteLine(0,DataA); / 沒(méi)有定義為public void IPartB.SetDataB(string dataB) DataB=dataB; Console.WriteLine(0,DataB); ,2. 接口的實(shí)現(xiàn),顯式接口成員只能通過(guò)接口來(lái)調(diào)用。 class test static void Main() SharedClass a = new SharedClass(); IPartB partb = a;

54、partb.SetDataA(interface IPartA); partb.SetDataB(interface IPartB); 方法本身并不是類(lèi)SharedClass提供,a.SetDataA(interface IPartA)或a.SetDataB(interface IPartB)調(diào)用都是錯(cuò)誤的。顯式接口成員沒(méi)被聲明為public,這是因?yàn)檫@些方法都有著雙重的身份。當(dāng)在一個(gè)類(lèi)中使用顯式接口成員時(shí),該方法被認(rèn)為是私有方法,因此不能用類(lèi)的實(shí)例調(diào)用它。但是,當(dāng)將類(lèi)的引用轉(zhuǎn)型為接口引用時(shí),接口中定義的方法就可以被調(diào)用,這時(shí)它又成為了一個(gè)公有方法。,2. 接口的實(shí)現(xiàn),【例4.15】顯式接口調(diào)

55、用 using System; public interface IWindow Object GetMenu(); public interface IRestaurant Object GetMenu(); / 該類(lèi)型繼承自system.Object,并實(shí)現(xiàn)了IWindow和IRestaurant 接口 public class GiuseppePizzaria : IWindow, IRestaurant / 該方法包括了IWindow接口的GetMenu方法實(shí)現(xiàn) Object IWindow.GetMenu() return IWindow.GetMenu; ,【例4.15】,/ 該方法包括了IRestaurant接口的GetMenu方法實(shí)現(xiàn) Object IRestaurant.GetMenu() return IRestaurant.GetMenu; / 這個(gè)GetMenu方法與接口沒(méi)有任何關(guān)系 public Object GetMenu

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論