知识结构:
图1知识结构5、属性例1:属性概念的引入(问题)
图2ClassDiagrampublicclassAnimal{publicintAge;publicdoubleWeight;publicboolSex;publicAnimal(intage,doubleweight,boolsex){Age=age;Weight=weight;Sex=sex;}publicvoidEat(){Console.WriteLine("AnimalEat.");}publicvoidSleep(){Console.WriteLine("AnimalSleep.");}publicoverridestringToString(){returnstring.Format("AnimalAge:{0},Weight:{1},Sex:{2}",Age,Weight,Sex);}}classProgram{staticvoidMain(string[]args){Animalal=newAnimal(1,1.2,false);Console.WriteLine("AnimalAge:{0},Weight:{1},Sex:{2}",al.Age,al.Weight,al.Sex);//AnimalAge:1,Weight:1.2,Sex:Falseal.Age=-1;al.Weight=-0.5;Console.WriteLine(al);//AnimalAge:-1,Weight:-0.5,Sex:False}}
例2:问题的解决(Java语言解决该问题的方案)
图3ClassDiagrampublicclassAnimal{privateint_age;privatedouble_weight;privatereadonlybool_sex;publicintGetAge(){return_age;}publicvoidSetAge(intvalue){_age=(value0)?value:0;}publicdoubleGetWeight(){return_weight;}publicvoidSetWeight(doublevalue){_weight=(value0)?value:0;}publicboolGetSex(){return_sex;}publicAnimal(intage,doubleweight,boolsex){_age=(age0)?age:0;_weight=(weight0)?weight:0;_sex=sex;}publicvoidEat(){Console.WriteLine("AnimalEat.");}publicvoidSleep(){Console.WriteLine("AnimalSleep.");}publicoverridestringToString(){returnstring.Format("AnimalAge:{0},Weight:{1},Sex:{2}",_age,_weight,_sex);}}classProgram{staticvoidMain(string[]args){Animalal=newAnimal(1,1.2,false);Console.WriteLine("AnimalAge:{0},Weight:{1},Sex:{2}",al.GetAge(),al.GetWeight(),al.GetSex());//AnimalAge:1,Weight:1.2,Sex:Falseal.SetAge(-1);al.SetWeight(-0.5);Console.WriteLine(al);//AnimalAge:0,Weight:0,Sex:False}}
例3:属性的提出
图4ClassDiagrampublicclassAnimal{privateint_age;privatedouble_weight;privatereadonlybool_sex;publicintAge{get{return_age;}set{_age=(value0)?value:0;}}publicdoubleWeight{get{return_weight;}set{_weight=(value0)?value:0;}}publicboolSex{get{return_sex;}}publicAnimal(intage,doubleweight,boolsex){_age=(age0)?age:0;_weight=(weight0)?weight:0;_sex=sex;}publicvoidEat(){Console.WriteLine("AnimalEat.");}publicvoidSleep(){Console.WriteLine("AnimalSleep.");}publicoverridestringToString(){returnstring.Format("AnimalAge:{0},Weight:{1},Sex:{2}",Age,Weight,Sex);}}classProgram{staticvoidMain(string[]args){Animalal=newAnimal(1,1.2,false);Console.WriteLine("AnimalAge:{0},Weight:{1},Sex:{2}",al.Age,al.Weight,al.Sex);//AnimalAge:1,Weight:1.2,Sex:Falseal.Age=-1;al.Weight=-0.5;Console.WriteLine(al);//AnimalAge:0,Weight:0,Sex:False}}
说明:C#在声明data时就可以定义set、get方法。
get:定义读取操作。set:定义赋值操作,value表示传入的参数值。例4:属性的简化
图5ClassDiagrampublicclassAnimal{privateint_age;privatedouble_weight;publicintAge{get{return_age;}set{_age=(value0)?value:0;}}publicdoubleWeight{get{return_weight;}set{_weight=(value0)?value:0;}}publicboolSex{get;privateset;}publicAnimal(intage,doubleweight,boolsex){_age=(age0)?age:0;_weight=(weight0)?weight:0;Sex=sex;}publicvoidEat(){Console.WriteLine("AnimalEat.");}publicvoidSleep(){Console.WriteLine("AnimalSleep.");}publicoverridestringToString(){returnstring.Format("AnimalAge:{0},Weight:{1},Sex:{2}",Age,Weight,Sex);}}classProgram{staticvoidMain(string[]args){Animalal=newAnimal(1,1.2,false);Console.WriteLine("AnimalAge:{0},Weight:{1},Sex:{2}",al.Age,al.Weight,al.Sex);//AnimalAge:1,Weight:1.2,Sex:Falseal.Age=-1;al.Weight=-0.5;Console.WriteLine(al);//AnimalAge:0,Weight:0,Sex:False}}6、索引器
6.1定义
是集合类中的一种特殊属性,可使得集合类中的元素像数组元素一样访问。
6.2语法结构
public元素类型this[intindex]{get{...}set{...}}public元素类型this[stringname]{get{...}set{...}}
例5:利用索引器实现对集合类StudentSet中元素Student的访问。
图6ClassDiagrampublicclassStudent{privatestring_name;publicstringName{get{return_name;}set{_name=string.IsNullOrEmpty(value)?"NULL":value;}}publiclongID{get;set;}publicStudent(longid,stringname){ID=id;_name=name;}publicoverridestringToString(){returnstring.Format("ID:{0},Name:{1}",ID,Name);}}publicclassStudentSet{privatereadonlyint_maxCount=;privatereadonlyStudent[]_stus;publicintCount{get;privateset;}publicStudentSet(){Count=0;_stus=newStudent[_maxCount];}publicvoidAdd(Studentstu){if(stu==null)thrownewArgumentNullException();if(Count==_maxCount)thrownewIndexOutOfRangeException();_stus[Count]=stu;Count++;}publicStudentthis[intindex]{get{if(index0
indexCount-1)thrownewIndexOutOfRangeException();return_stus[index];}set{if(index0
indexCount-1)thrownewIndexOutOfRangeException();if(value==null)thrownewArgumentNullException();_stus[index]=value;}}}classProgram{staticvoidMain(string[]args){StudentSetstuSet=newStudentSet();stuSet.Add(newStudent(,"张三"));stuSet.Add(newStudent(,"李四"));stuSet[1].Name=string.Empty;Console.WriteLine(stuSet.Count);//2Console.WriteLine(stuSet[0]);//ID:,Name:张三Console.WriteLine(stuSet[1]);//ID:,Name:NULLConsole.WriteLine(stuSet[2]);//未处理的异常:System.IndexOutOfRangeException:索引超出了数组界限。}}7、接口
7.1概念
接口是类设计的蓝图,即只提供声明而没有实现。接口不可以直接实例化对象(与抽象类相同)。C#允许一个类实现多个接口(注意与继承的区别)。接口就是包含一系列不被实现的方法,而把这些方法的实现交给继承它的类。7.2表示
图7ClassDiagram例6:根据类图利用Dog实现IAnimal接口
图8ClassDiagrampublicinterfaceIAnimal{intAge{get;set;}doubleWeight{get;set;}voidEat();voidSleep();}publicclassDog:IAnimal{privateint_age;privatedouble_weight;publicintAge{get{return_age;}set{_age=(value=0)?value:0;}}publicdoubleWeight{get{return_weight;}set{_weight=(value=0)?value:0;}}publicvoidEat(){Console.WriteLine("DogEat");}publicvoidSleep(){Console.WriteLine("DogSleep");}}classProgram{staticvoidMain(string[]args){IAnimalal=newDog();al.Age=1;al.Weight=2.5;Console.WriteLine("Dog:Age={0},Weight={1}",al.Age,al.Weight);//Dog:Age=1,Weight=2.5al.Eat();//DogEatal.Sleep();//DogSleep}}
例7:利用接口实现“饲养系统”
某饲养员(Raiser)在目前状态下需要饲养三种动物:狗(Dog)、鸟(Bird)和鱼(Fish),该三种动物只需要让其睡觉(Sleep)和吃饭(Eat)即可。请设计该饲养系统,要求满足软件设计的“开闭原则”。
方案一:(在抽象类部分已经给出)
图9利用抽象类实现饲养系统方案二:
图10利用接口实现饲养系统publicinterfaceIAnimal{intAge{get;set;}doubleWeight{get;set;}voidEat();voidSleep();}publicclassBird:IAnimal{privateint_age;privatedouble_weight;publicintAge{get{return_age;}set{_age=(value=0)?value:0;}}publicdoubleWeight{get{return_weight;}set{_weight=(value=0)?value:0;}}publicvoidEat(){Console.WriteLine("BirdEat.");}publicvoidSleep(){Console.WriteLine("BirdSleep.");}publicvoidFly(){Console.WriteLine("BirdFly.");}}publicclassDog:IAnimal{privateint_age;privatedouble_weight;publicintAge{get{return_age;}set{_age=(value=0)?value:0;}}publicdoubleWeight{get{return_weight;}set{_weight=(value=0)?value:0;}}publicvoidEat(){Console.WriteLine("DogEat.");}publicvoidSleep(){Console.WriteLine("DogSleep.");}publicvoidRun(){Console.WriteLine("DogRun.");}}publicclassFish:IAnimal{privateint_age;privatedouble_weight;publicintAge{get{return_age;}set{_age=(value=0)?value:0;}}publicdoubleWeight{get{return_weight;}set{_weight=(value=0)?value:0;}}publicvoidEat(){Console.WriteLine("FishEat.");}publicvoidSleep(){Console.WriteLine("FishSleep.");}publicvoidSwim(){Console.WriteLine("FishSwim.");}}publicclassRaiser{publicvoidRaise(IAnimalal){al.Eat();al.Sleep();}}classProgram{staticvoidMain(string[]args){Raiserrsr=newRaiser();rsr.Raise(newDog());//DogEat.//DogSleep.rsr.Raise(newBird());//BirdEat.//BirdSleep.rsr.Raise(newFish());//FishEat.//FishSleep.}}
7.3接口(interface)与抽象类(abstractclass)
(1)相同点:
接口与抽象类都不可以直接实例化对象。(2)不同点:
抽象类中的数据和操作必须有限制修饰符,而接口中的数据和操作不可以有限制修饰符。抽象类中可以有带实现体的方法(非abstract方法),而接口只能有方法的声明。抽象类在子类中通过override关键字覆写抽象方法,而接口被子类直接实现。例8:一个类可以实现多个接口,但要注意多个接口中有重名方法的处理。
方式一:
图11ClassDiagrampublicinterfaceIHighWayWorker{voidHighWayOperation();voidBuild();}publicinterfaceIRailWayWorker{voidRailWayOperation();voidBuild();}publicclassWorker:IRailWayWorker,IHighWayWorker{publicvoidHighWayOperation(){Console.WriteLine("HighWayOperation.");}publicvoidRailWayOperation(){Console.WriteLine("RailWayOperation");}publicvoidBuild(){Console.WriteLine("HighWay,RailWay,Build.");}}classProgram{staticvoidMain(string[]args){Workerwr=newWorker();wr.Build();//HighWay,RailWay,Build.IHighWayWorkerhwr=newWorker();hwr.Build();//HighWay,RailWay,Build.hwr.HighWayOperation();//HighWayOperation.IRailWayWorkerrwr=newWorker();rwr.Build();//HighWay,RailWay,Build.rwr.RailWayOperation();//RailWayOperation}}
方式二:
图12ClassDiagrampublicinterfaceIHighWayWorker{voidHighWayOperation();voidBuild();}publicinterfaceIRailWayWorker{voidRailWayOperation();voidBuild();}publicclassWorker:IHighWayWorker,IRailWayWorker{publicvoidHighWayOperation(){Console.WriteLine("HighWayOperation.");}publicvoidRailWayOperation(){Console.WriteLine("RailWayOperation");}voidIHighWayWorker.Build(){Console.WriteLine("HighWayBuild.");}voidIRailWayWorker.Build(){Console.WriteLine("RailWayBuild.");}//注意:voidIHighWayWorker.Build()和voidIRailWayWorker.Build()//前面不能够加限制修饰符。}classProgram{staticvoidMain(string[]args){Workerwr=newWorker();//wr.Build();该语句错误IHighWayWorkerhwr=newWorker();hwr.Build();//HighWayBuild.hwr.HighWayOperation();//HighWayOperation.IRailWayWorkerrwr=newWorker();rwr.Build();//RailWayBuild.rwr.RailWayOperation();//RailWayOperation}}8、泛型
例9:存储int数据类型的集合及操作。
publicclassIntSet{privatereadonlyint_maxSize;privatereadonlyint[]_set;publicIntSet(){_maxSize=;_set=newint[_maxSize];//...}publicvoidInsert(intk,intx){//...._set[k]=x;}publicintLocate(intk){//...return_set[k];}}classProgram{staticvoidMain(string[]args){IntSetiSet=newIntSet();iSet.Insert(0,);inti=iSet.Locate(0);Console.WriteLine(i);//}}
例10:存储string数据类型的集合及操作。
publicclassStringSet{privatereadonlyint_maxSize;privatereadonlystring[]_set;publicStringSet(){_maxSize=;_set=newstring[_maxSize];//...}publicvoidInsert(intk,stringx){//...._set[k]=x;}publicstringLocate(intk){//...return_set[k];}}classProgram{staticvoidMain(string[]args){StringSetstrSet=newStringSet();strSet.Insert(0,"abc");stringj=strSet.Locate(0);Console.WriteLine(j);//abc}}
例11:利用object类存储通用数据类型的集合及操作。
publicclassGSet{privatereadonlyintmaxSize;privatereadonlyobject[]_set;publicGSet(){maxSize=;_set=newobject[maxSize];//...}publicvoidInsert(intk,objectx){//...._set[k]=x;}publicobjectLocate(intk){//...return_set[k];}}classProgram{staticvoidMain(string[]args){GSetgSet1=newGSet();gSet1.Insert(0,);intk1=(int)gSet1.Locate(0);Console.WriteLine(k1);//GSetgSet2=newGSet();gSet2.Insert(0,"abc");stringk2=(string)gSet2.Locate(0);Console.WriteLine(k2);//abcGSetgSet3=newGSet();gSet3.Insert(0,);gSet3.Insert(1,"abc");//编译时可以通过,运行时出现异常。intk3=(int)gSet3.Locate(1);//这样使用存在类型安全问题。Console.WriteLine(k3);//未处理的异常:System.InvalidCastException:指定的转换无效。}}
泛型定义:即参数化类型。
在编译时用一个具体类型代替该参数类型,可定义类型安全的类而不影响工作效率。
例12:利用泛型T存储通用数据类型的集合及操作。
publicclassGSetT{privatereadonlyint_maxSize;privatereadonlyT[]_set;publicGSet(){_maxSize=;_set=newT[_maxSize];//...}publicvoidInsert(intk,Tx){//...._set[k]=x;}publicTLocate(intk){//...return_set[k];}}classProgram{staticvoidMain(string[]args){GSetintgSet1=newGSetint();gSet1.Insert(0,);intk1=gSet1.Locate(0);Console.WriteLine(k1);//GSetstringgSet2=newGSetstring();gSet2.Insert(0,"abc");stringk2=gSet2.Locate(0);Console.WriteLine(k2);//abc}}
我们把T称为类型参数,当然我们也可以对T进行约束。
例13:为类型参数T增加约束,比如T只能是值类型。
publicclassGSetTwhereT:struct{privatereadonlyint_maxSize;privatereadonlyT[]_set;publicGSet(){_maxSize=;_set=newT[_maxSize];//...}publicvoidInsert(intk,Tx){//...._set[k]=x;}publicTLocate(intk){//...return_set[k];}}classProgram{staticvoidMain(string[]args){GSetintgSet1=newGSetint();gSet1.Insert(0,);intk1=gSet1.Locate(0);Console.WriteLine(k1);////GSetstringgSet2=newGSetstring();//编译错误//错误CS类型“string”必须是不可以为null值的类型,//才能用作泛型类型或方法“GSetT”中的参数“T” }}
有关泛型约束可以查看以下图文:
技术图文:C#语言中的泛型I技术图文:C#语言中的泛型II9、类与类之间的关系图13依赖关系publicclassOxygen{//...}publicclassWater{//...}publicabstractclassAnimal{publicintAge;publicdoubleWeight;publicabstractvoidEat();publicabstractvoidSleep();publicabstractvoidBreed();publicabstractvoidMetabolism(Oxygeno2,Waterwater);}图14继承关系
publicclassBird:Animal{publicstringFeather;publicvoidFly(){//...}publicvoidEgg(){//...}publicoverridevoidEat(){//...}publicoverridevoidSleep(){//...}publicoverridevoidBreed(){//...}publicoverridevoidMetabolism(Oxygeno2,Waterwater){//...}}publicclassPenguin:Bird{//...}publicclassGoose:Bird{//...}publicclassDuck:Bird{//...}图15关联关系
publicclassClimate{//...}publicclassPenguin:Bird{privateClimate_climate;//...}图16实现关系
publicinterfaceILanguage{voidSpeak();}publicclassDonaldDuck:Duck,ILanguage{publicvoidSpeak(){//...}//...}
后台回复「搜搜搜」,随机获取电子资源!欢迎