版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第3章面向对象编程基础1.理解基本概念2.理解类3.使用构造函数4.学习方法5.学习属性掌握1
姓名、性别、年龄等:属性学习课程、参加社会活动:方法3.1面向对象编程概念1.对象——具有属性和操作(方法)的实体。 属性:对象所处的状态 方法:用于改变对象状态以达到特定的功能 对象有一个唯一的标识名2.类——在对象之上的抽象,一种抽象的数据类型3.类是对象的模板,对象是类的具体化或类的实例示例: 学生——类 各位同学——对象2对象与类属性型号价格里程行为起动停车行驶属性车轮数量档的数量行为加速换档刹车属性名称颜色品种行为摇尾巴吃东西犬吠3面向对象程序设计在处理对象时,
必须遵循的三个原则:1.封装
用一个框架把数据和代码组合在一起,形成一个对象。类是支持对象封装的工具,对象则是封装的基本单元。2.继承
利用继承可以创建分等级层次的类,继承是父类和子类之间共享数据和方法的机制,通常把父类称为基类,子类称为派生类。 单继承:一个基类可以有任意数目的派生类,即一父多子 多继承:一个类若有两个或两个以上的直接基类,即一子多父,称为多重继承,C#通过接口来实现3.多态性
同一个操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。分为静态多态和动态多态根据参数的差别直接调用对象方法根据基类间接调用对象方法43.2类3.2.1类的声明语法形式:[属性集信息][类修饰符]class类名[:类基]{ [类主体]}属性集信息——是C#语言为程序中定义的各种实体附加一些说明信息,是C#语言的一个重要特征。属于高级编程内容,一般涉及不到。类名:唯一标识名类基:直接基类或接口。默认基类是object类,多个接口之间用逗号相隔类修饰符——访问权限、类的类型等,注意同一修饰符不允许出现多次,见表3.15表3.1类修饰符修饰符作用说明public表示不限制对类的访问。类的访问权限省略时默认为publicprotected表示该类只能被这个类的成员或派生类成员访问private表示该类只能被这个类的成员访问,很少用internal表示该类能够由程序集中的所有文件使用,而不能由程序集之外的对象使用new只允许用在嵌套类中,它表示所修饰的类会隐藏继承下来的同名成员abstract表示这是一个抽象类,该类含有抽象成员,因此不能被实例化,只能用作基类sealed表示这是一个密封类,不能从这个类再派生出其他类。显然密封类不能同时为抽象类示例:classStudent{//类主体}63.2.2类的成员类体(类主体)用于定义该类的成员
用一对花括号{}括起来,由两部分组成:
1.类体中以类成员声明形式引入的类成员
包括:常数声明、字段声明、方法声明、属性声明、事件声明、索引器声明、运算符声明、构造函数声明、析构函数声明、静态构造函数、类型声明等
2.直接从基类继承而来的成员7一、成员类型:(1)静态成员在字段、方法、属性、事件、运算符和构造函数声明中含有publicstatic修饰符(2)实例成员在字段、方法、属性、事件、运算符和构造函数声明中不含有publicstatic修饰符二、默认成员访问修饰符——private
类成员注意点:8classProgram{classAClass{
publicstaticintx=1;
publicinty=2;}
staticvoidMain(string[]args){
AClassab=newAClass();Console.WriteLine("y={0},x={1}",ab.y,AClass.x);}}91.常数声明语法形式:[属性集信息][常数修饰符]const类型标识符=常数表达式[,…]常数修饰符——new、public、protected、private、
internalpublic:访问不受限制protected:访问仅限于包含类或从包含类派生的类型internal:访问仅限于当前程序集。private:访问仅限于包含类。类型——sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、string、枚举类型或引用类型。常数表达式的值类型应与目标类型一致,或者通过隐式转换规则转换成目标类型。10112.字段声明语法形式:[属性集信息][字段修饰符]类型变量声明列表;变量声明列表——标识符或用逗号“,”分隔的多个标识符,并且变量标识符还可用赋值号“=”设定初始值。字段修饰符——new、public、protected、private、internal、static、readonly、volatilestatic:静态变量。利用类直接访问静态变量,利用类的实例(对象)访问非静态变量readonly:只读变量,声明时或在构造函数中赋值,一旦赋值不可改变。与const常量不同,const常量编译时赋值计算。volatile:表示字段可能被多个并发执行的进程修改。12【例3.1】通过构造函数给只读字段赋值出错了!无法修改只读字段133.2.3构造函数和析构函数1.构造函数 (1)实现对象初始化 (2)分为实例构造函数和静态构造函数 (3)函数调用时机:new1)实例构造函数的声明语法形式:[属性集信息][构造函数修饰符]标识符([参数列表])[:base([参数列表])][:this([参数列表])]{构造函数语句块}public与类名相同没有返回值构造函数重载:参数个数或类型不同调用基类同参数列表的构造函数调用本类同参数列表的构造函数14构造函数修饰符 ——public、protected、internal、private、extern一般地,构造函数总是public类型的。如果是private类型的,表明类不能被外部类实例化。标识符([参数列表]opt)——构造函数名必须与这个类同名,无返回类型和返回值构造函数可以有0~n个参数——构造函数重载3.用new运算符创建一个类的对象时,类名后的一对圆括号提供初始化列表,系统根据这个初始化列表的参数个数、参数类型和参数顺序调用不同的构造函数。实例构造函数注意点:15classTest{staticvoidMain() {Timet1,t2,t3,t4;//对t1,t2,t3,t4分别调用不同的构造函数t1=newTime();t2=newTime(8);t3=newTime(8,30);t4=newTime(8,30,30);}}【例3.2】Time类的构造函数及其重载usingSystem;publicclassTime{privateinthour,minute,second;publicTime(){hour=minute=second=0;}publicTime(inth){hour=h;minute=second=0;}publicTime(inth,intm){hour=h;minute=m;second=0;}publicTime(inth,intm,ints){hour=h;minute=m;second=s;}}publicstringgetTime(){returnhour.ToString()+":"+minute.ToString()+":"+second.ToString();}Console.WriteLine("t1={0}",t1.getTime());16【例3.3】
构造函数初始化a.x=0,a.y=0b.x=3,b.y=417构造函数注意点:若类中没有提供构造函数,则CLR会自动提供一个默认的构造函数一旦类中提供了自定义的构造函数,系统则不提供默认的构造函数不必显示调用构造函数实例构造函数不能被继承18派生类构造函数的调用调用时机:创建派生类的对象时,即new构造函数不被继承派生类构造函数在执行前,首先显式或隐式地调用基类构造函数默认调用基类的无参数构造函数除非显式地指定调用有参数构造函数this关键字引用类的当前实例base关键字用于从派生类中访问基类的成员调用基类上已被其他方法重写的方法指定创建派生类实例时应调用的基类构造函数19【例3.4】派生类构造函数及其调用usingSystem;classPoint{privateintx,y;publicPoint(){x=0;y=0;Console.WriteLine("Point()constructor:{0}",this);}publicPoint(intx,inty){this.x=x;this.y=y;Console.WriteLine("Point(x,y)constructor:{0}",this);}}classCircle:Point{privatedoubleradius;publicCircle() //默认约定调用基类的无参构造函数Point(){Console.WriteLine("Circle()constructor:{0}",this);}publicCircle(doubleradius):base(){this.radius=radius;Console.WriteLine("Circle(radius)constructor:{0}",this);}publicCircle(intx,inty,doubleradius):base(x,y){this.radius=radius; Console.WriteLine("Circle(x,y,radius)constructor:{0}",this);}}13254202)静态构造函数的声明语法形式:[属性集信息][静态构造函数修饰符]标识符(){ 静态构造函数体}
静态构造函数修饰符——[extern]static或者static[extern]。如有extern修饰,则是一个外部静态构造函数,不提供任何实际的实现,静态构造函数体仅仅是一个分号标识符——是静态构造函数名,必须与类同名且不能有参数静态构造函数体——只能对静态数据成员进行初始化21静态构造函数不可继承,不能直接调用调用时机:创建类的实例引用类的任何静态成员至多被执行一次若类没有声明静态构造函数,而又包含带有初始设定的静态字段时,编译器会自动生成一个默认的静态构造函数静态构造函数注意点:222.析构函数语法形式:[属性集信息][extern]~标识符(){析构函数体}
标识符——必须与类名相同,前面需加“~”
析构函数——不能写返回类型,也不能带参数,一个类最多只能有一个析构函数23析构函数注意点析构函数不能由程序显式地调用,而是由系统在释放对象时自动调用派生类对象的析构函数调用链:1)执行派生类的析构函数2)执行基类的析构函数,直到调用object类的析构函数为止与执行构造函数的顺序相反24第3章面向对象编程基础1.理解基本概念2.理解类3.使用构造函数4.学习方法5.学习属性掌握25回顾对象
——具有属性和操作(方法)的实体类
——对象的抽象,抽象的数据类型类是对象的模板对象是类的具体化或类的实例26类的成员1.类体中以类成员声明形式引入的类成员包括:常数声明、字段声明、构造函数声明、析构函数声明、静态构造函数、方法声明、属性声明等2.直接从基类继承而来的成员27访问修饰符public访问不受限制protected只能被本身或派生类的实例访问private只能被本身访问static静态,非实例28构造函数构造函数——实例构造函数与类名同名在类进行new运算(即类实例化时)this:引用当前类的实例base:用于从派生类中访问基类的成员调用基类上已被其他方法重写的方法指定创建派生类实例时应该调用的基类构造函数调用顺序先基类后派生类293.3方法3.3.1方法的声明语法形式:[属性集信息][方法修饰符]返回类型方法名([形参表]){ 方法体}1.C#中所有的变量、方法都必须封装在类中2.对象间、类间只能通过类所提供的方法进行互操作3.从方法的声明、方法的参数、静态方法与实例方法、方法的重载与覆盖等方面理解30表3.2方法修饰符修饰符作用说明new在一个继承结构中,用于隐藏基类同名的方法public表示该方法可以在任何地方被访问,默认publicprotected表示该方法可以在它的类体或派生类类体中被访问,但不能在类体外访问private表示该方法只能在这个类体内被访问internal表示该方法可以被同处于一个工程的文件(程序集)访问static表示该方法属于类本身,而不属于某特定对象virtual表示该方法可在派生类中重写,来更改该方法的实现abstract表示该方法仅仅定义了方法名及执行方式,但没有给出具体实现,所以包含这种方法的类是抽象类,有待于派生类的实现override表示该方法是将从基类继承的virtual方法的新实现sealed表示这是一个密封方法,它必须同时包含override修饰,以防止它的派生类进一步重写该方法extern表示该方法从外部实现31表3.3修饰符的无效组合修饰符不能与下列选项一起使用staticvirtual、abstract和overridevirtualstatic、abstract和overrideoverridenew、static和virtualabstractvirtual和staticnewoverrideexternabstract返回类型——方法可以返回值也可以不返回值。 返回值类型为任意一种C#的数据类型,通过return语句返回。如果方法不返回值,则它的返回类型可标为void,默认情况下为void方法名:除Main()、关键字以外32【例3.6】
下面程序中的StackTp类定义了几个方法以模拟实现一个压栈操作。usingSystem;classStackTp{intMaxSize;intTop;int[]StkList;publicStackTp()//构造函数{MaxSize=100;Top=0;StkList=newint[MaxSize];}publicStackTp(intsize)//构造函数{MaxSize=size;Top=0;StkList=newint[MaxSize];}publicboolisEmptyStack()//方法{if(Top==0)returntrue;else returnfalse;}publicboolisFullStack(){if(Top==MaxSize) returntrue;else returnfalse;}publicvoidpush(intx){StkList[Top]=x;Top++;}}333.3.2方法的参数形参(形式参数):声明方法时包含的方法参数说明实参(实际参数):调用方法时给出的实际参数在C#中实参与形参有4种传递方式:值参数引用参数——ref输出参数——out参数数组——params1.值参数
在方法声明时不加修饰的形参就是值参数,它表明实参与形参之间按值传递在方法中对形参的修改不影响外部的实参属于输入参数34usingSystem;classMyclass{publicvoidSort(intx,inty,intz){inttmp;//tmp是方法Sort的局部变量//将x,y,z按从小到大排序if(x>y){tmp=x;x=y;y=tmp;}if(x>z){tmp=x;x=z;z=tmp;}if(y>z){tmp=y;y=z;z=tmp;}//Console.WriteLine(“x={0},y={1},z={2}"
x,y,z);}}classTest{staticvoidMain(){Myclassm=newMyclass();inta,b,c;a=30;b=20;c=10;m.Sort(a,b,c);Console.WriteLine("a={0},b={1},c={2}",a,b,c);Console.Read();}}【例3.7】
演示了当方法Sort传递的是值参数时,对形参的修改不影响其实参。35是值参数传递方式,形参另外分配一块内存,接受实参的引用值副本1.对引用值的修改不会影响实参2.如果改变的是所引用的对象,则将会影响实参所引用的对象值参数——传递引用对象内存首地址36usingSystem;classMyclass{publicvoidSortArray(int[]a){inti,j,pos,tmp;for(i=0;i<a.Length
1;i++){for(pos=j=i;j<a.Length;j++)if(a[pos]>a[j])pos=j;if(pos!=i){ tmp=a[i]; a[i]=a[pos]; a[pos]=tmp;}}}}classTest{staticvoidMain(){Myclassm=newMyclass();int[]score={87,89,56,90,100,75,64,45,80,84};m.SortArray(score);for(inti=0;i<score.Length;i++){ Console.Write("score[{0}]={1},",i,score[i]);if(i==4)Console.WriteLine();}Console.Read();}}【例3.8】
程序演示的是当方法传递的是一个引用对象(如数组)时,对形参的修改会影响到实参改变了引用的对象查询最小值372.引用参数引用参数——形参的改变影响实参例3.7中实际变量a、b、c是不随形参x、y、z的,但如果想改变实际变量a、b、c的值,则用引用参数38usingSystem;classMyclass{publicvoidSort(intx,inty,intz){inttmp;//tmp是方法Sort的局部变量//将x,y,z按从小到大排序if(x>y){tmp=x;x=y;y=tmp;}if(x>z){tmp=x;x=z;z=tmp;}if(y>z){tmp=y;y=z;z=tmp;}//Console.WriteLine(“x={0},y={1},z={2}"
x,y,z);}}classTest{staticvoidMain(){Myclassm=newMyclass();inta,b,c;a=30;b=20;c=10;m.Sort(a,b,c);Console.WriteLine("a={0},b={1},c={2}",a,b,c);Console.Read();}}【例3.7】
演示了当方法Sort传递的是值参数时,对形参的修改不影响其实参。392.引用参数引用参数——形参的改变影响实参例3.7中实际变量a、b、c是不随形参x、y、z的,但如果想改变实际变量a、b、c的值,则用引用参数C#用ref修饰符声明引用参数引用参数不创建新的存储单元,与方法调用中的实际参数变量同处一个存储单元——传递内存地址属于输入参数40【例3.9】将例3.7程序中Sort方法的值参数传递方式改成引用参数传递,这样在方法Sort中对参数x、y、z按从小到大的排序影响了调用它的实参a、b、c。usingSystem;classMyclass{ publicvoidSort(refintx,refinty,refintz){inttmp;//tmp是方法Sort的局部变量 //将x,y,z按从小到大排序if(x>y){tmp=x;x=y;y=tmp;}if(x>z){tmp=x;x=z;z=tmp;}if(y>z){tmp=y;y=z;z=tmp;}}}41使用ref声明引用参数的注意:(1)方法的参数声明中ref关键字仅对紧跟在它后面的参数有效,而不能应用于整个参数表。 例如,Sort方法中x、y、z都要加ref修饰(2)在方法的调用中也要用ref修饰实参,且实参必须为变量,实参和形参的数据类型必须完全匹配(3)在方法外(方法调用前),ref参数必须明确赋值(4)ref参数也可以用于传递引用类型的对象42第3章面向对象编程基础方法声明——如同C语言的“函数”访问修饰符默认为public方法参数值参数(值类型、引用类型)引用参数——ref输出参数——out参数数组——params方法43方法重载与覆盖方法签名方法覆盖——new和虚方法virtualoverride属性propertyget访问器set访问器443.输出参数1.用法与ref参数相似,但为输出参数值2.只能用于从方法中传出值, 因此必须在方法结束之前对out参数赋值3.在参数前加out修饰符的形式参数4.out参数也可以用于传递引用类型的对象45classTest{staticvoidMain(){Myclassm=newMyclass();int[]score={87,89,56,90,100,75,64,45,80,84};intsmax,smin;doublesavg;m.MaxMinArray(score,outsmax,outsmin,outsavg);Console.Write("Max={0},Min={1},Avg={2}",smax,smin,savg);Console.Read();}}【例3.10】求一个数组中元素的最大值、最小值和平均值。usingSystem;classMyclass{publicvoidMaxMinArray(int[]a,outintmax,outintmin,outdoubleavg){ intsum; sum=max=min=a[0]; for(inti=1;i<a.Length;i++) { if(a[i]>max)max=a[i]; if(a[i]<min)min=a[i]; sum+=a[i]; } avg=sum/a.Length;}}46【例3.11】下面程序定义了两个方法,一个是Swap1,一个是Swap2,它们都有两个引用对象作为参数,但Swap2的参数加了ref修饰,调用这两个方法产生的结果是不一样的。usingSystem;classMyclass{publicvoidSwap1(strings,stringt){stringtmp;tmp=s;s=t;t=tmp;}publicvoidSwap2(ref
strings,refstringt){stringtmp;tmp=s;s=t;t=tmp;}}s1,s2的引用并没有改变s1,s2的引用互相交换了474.参数数组3.3.3静态方法与实例方法特点:参数为可变长度使用params关键字来指定一个可变长度的参数表注意:1.一个方法中只能声明一个params参数2.params参数必须放在参数表最后3.params参数是一个一维数组,参数数组的参数:0~n4.params不可与ref、out修饰符组合使用1.静态方法用static修饰2.只能访问类中的静态成员48【例3.12】
下面程序演示了Myclass类中的方法MaxMin有一个参数数组类型的参数,在调用这个方法时具有灵活性。usingSystem;classMyclass{publicvoidMaxMin(outintmax,outintmin,paramsint[]a){
//如果可变参数为零个,//取一个约定值或产生异常if(a.Length==0){ max=min=
1; return;}max=min=a[0];for(inti=1;i<a.Length;i++){ if(a[i]>max)max=a[i]; if(a[i]<min)min=a[i];}}}493.3.4方法的重载与覆盖方法重载
同一个类中存在具有相同方法名,但具有不同的形式参数个数、修饰符及类型的两个或两个以上的方法。
重载是多态的形式之一。编译时根据调用时给出的实参个数和类型调用相应的方法,以实现多态
方法签名:方法名、形参个数、形参修饰符、形参类型一起构成方法签名50【例3.14】
下面程序定义的Myclass类中含有4个名为max的方法,但它们或者参数个数不同,或者参数类型不同,在Main调用该方法时,编译器会根据参数的个数和类型确定调用哪个max方法。usingSystem;classMyclass{publicintmax(intx,inty){returnx>=y?x:y;}publicdoublemax(doublex,doubley){returnx>=y?x:y;}publicintmax(intx,inty,intz){returnmax(max(x,y),z);}publicdoublemax(doublex,doubley,doublez){returnmax(max(x,y),z);}}
51方法的覆盖——使用new隐藏有相同签名的方法1.当派生类与基类有相同名称或签名的成员时,在派生类中默认隐藏基类成员,但提示警告2.在派生类成员声明中加new修饰符,可以取消警告信息3.基类对象被引用到派生类对象时,访问的仍是基类的方法静态多态52【例3.15】定义了一个基类Shape,含有字段域width和height,分别表示形状的宽和高,并定义了一个area方法,求形状的面积。它的派生类Triangle和Trapezia都用关键字new修饰了area方法usingSystem;classShape{protecteddoublewidth;protecteddoubleheight;publicShape(){width=height=0;}publicShape(doublex){width=height=x;}publicShape(doublew,doubleh){width=w;height=h;}
publicdoublearea(){returnwidth*height;}}classTriangle:Shape //三角形{publicTriangle(doublex,doubley):base(x,y){}
newpublicdoublearea() //派生类方法与基类方法同名,编译时会有警告信息{returnwidth*height/2;}}classTrapezia:Shape//梯形{doublewidth2;publicTrapezia(doublew1,doublew2,doubleh):base(w1,h){width2=w2;}
newpublicdoublearea()//加new隐藏基类的area方法{return(width+width2)*height/2;}}基类方法53虚方法:基类的方法用关键字virtual修饰对基类的虚方法重载:派生类用关键字override修饰与基类中虚方法有相同签名的方法注意:(1)不能将虚方法声明为静态的(static)(2)不能将虚方法声明为私有的(private)(3)覆盖方法必须与它相关的虚方法匹配(4)一个覆盖方法覆盖的必须是虚方法实现运行时多态(动态绑定)54【例3.16】将例3.15改写,Shape类中的方法area用virtual修饰,而派生类Triangle和Trapezia用override修饰area方法。usingSystem;classShape{protecteddoublewidth;protecteddoubleheight;publicShape(){ width=height=0;}publicShape(doublex){ width=height=x;}publicShape(doublew,doubleh){ width=w;height=h; }publicvirtualdoublearea()//基类中用virtual修饰符声明一个虚方法{ returnwidth*height;}}classTriangle:Shape//三角形{publicTriangle(doublex,doubley):base(x,y){}publicoverridedoublearea()//派生类中用override修饰符覆盖基类虚方法{returnwidth*height/2;}}classTrapezia:Shape//梯形{doublewidth2;publicTrapezia(doublew1,doublew2,doubleh):base(w1,h){width2=w2;}publicoverridedoublearea() 派生类中用override修饰符覆盖基类虚方法{return(width+width2)*height/2; }}派生类方法553.4属性property回顾一下例3.2(P51)。为了实现良好的数据封装和数据隐藏,类的字段成员的访问属性一般设置成private(默认)或protected利用public方法来访问私有的或受保护的字段56
publicstringgetTime(){returnhour.ToString()+":"+minute.ToString()+":"+second.ToString();}【例3.2】
Time类的构造函数及其重载usingSystem;publicclassTime{
privateinthour,minute,second;publicTime(){hour=minute=second=0;}publicTime(inth){hour=h;minute=second=0;}publicTime(inth,intm){hour=h;minute=m;second=0;}publicTime(inth,intm,ints){hour=h;minute=m;second=s;}}573.4属性
保持原有的数据封装和数据隐藏,类的字段成员的访问属性仍然设置成private(默认)或protected?????不利用public方法来访问私有的或受保护的字段
属性(property)属性值的读/写与字段域语法相同;利用get和set访问器实现属性值的读/写如何做??58语法形式:[属性集信息][属性修饰符]类型成员名{访问器声明}
属性修饰符——与方法修饰符(public,private,protected,…)相同,包括new、static、virtual、abstract、override和4种访问修饰符的合法组合,遵循相同的规则。
访问器声明——声明属性的访问器,get访问器或set访问器,或者两个语法形式:get//读访问器{…//访问器语句块}set//写访问器{…//访问器语句块}属性的声明方法591.get访问器
1.返回值类型与属性的类型相同 2.在语句块中的return语句必须有一个可隐式转换为属性类型的表达式2.set访问器
1.没有返回值 2.有一个隐式的值参数value,类型与属性的类型相同。3.属性的种类
1.读/写属性:同时包含get和set访问器的属性 2.只读/只写属性:只包含get或set访问器的属性属性中的访问器使用注意60【例3.17】对TextBox类的text、fontname、fontsize、multiline域提供属性方式的读/写访问。usingSystem;classTextBox{privatestringtext;privatestringfontname;privateintfontsize;privateboolmultiline;publicTextBox(){text="text1";fontname="宋体";fontsize=12;multiline=false;}publicstringText{//Text属性,可读可写get{ returntext;}set{ text=value;}}publicstringFontName{//FontName属性,只读属性get{ returnfontname;}}publicintFontSize{//FontSize属性,可读可写get{ returnfontsize;}set{ fontsize=value;}}publicboolMultiLine{//MultiLine属性,只写set{ multiline=value;}}}61【例3.18】定义Label类,设置Width和Heigh属性,分别存放两点之间在水平坐标轴和垂直坐标轴上的投影长度。usingSystem;classPoint{intx,y;publicintX{get{returnx;}}publicintY{get{returny;}}publicPoint(){x=y=0; }publicPoint(intx,inty){this.x=x;this.y=y;}}classLabel{Pointp1=newPoint();Pointp2=newPoint(5,10);publicintWidth//计算两点之间在水平坐标轴上的投影长度{get{returnp2.X
p1.X;}}publicintHeight//计算两点之间在垂直坐标轴上的投影长度{get{returnp2.Y
p1.Y;}}}623.5综合应用实例
【例3.19】学生成绩管理程序。根据学生选修的课程及课程学分和课程成绩计算GPA,最后按GPA的值对学生进行排序。基本思路:本程序的学生总人数、课程名、课程学分可以由控制台输入,为叙述简单,假定每个学生所选修的课程相同。Course类中定义了课程名、课程学分字段域,Name属性、构造函数。Student类中定义字段:学生姓名、学号、选修课程数、Course类对象数组、成绩和GPA等属性:CourseNum静态属性、GPA属性、Name属性方法: SetCourse方法——设置课程名,静态方法 AddData方法——给每个学生加入姓名、学号、成绩。 ComputeGPA方法——计算学生成绩的GPA stuSwap方法——对两个Student对象内容进行交换。63classCourse{ stringcourseName; //课程名 intcourseMark; //课程学分 publicCourse() { } publicCourse(stringName,intMark) { courseName=Name; courseMark=Mark; } publicstringName //Name属性,课程名可读可写 { get { returncourseName; } set { courseName=value; } } publicintMark //Mark属性,课程学分可读可写 { get { returncourseMark; } set { courseMark=value; } }}64classStudent{ stringstuName;//学生姓名 stringstuID;//学生学号 staticintnumberOfCourse; staticCourse[]list;
int[]stuScore;//每个学生对象的各课程成绩 doublestuGPA;//GPA值 publicStudent() { list=newCourse[numberOfCourse]; for(inti=0;i<numberOfCourse;i++) list[i]=newCourse(); stuScore=newint[numberOfCourse]; }
加static修饰符表明这个域为所有学生类对象共享Course类对象数组,用于设置每门课程名、课程学分65//将CourseNum定义成静态属性是因为它只对静态域进行操作 publicstaticintCourseNum { get { returnnumberOfCourse; } set { numberOfCourse=value; } } publicdoubleGPA//GPA属性是只读属性 { get { returnstuGPA; } } publicstringName//Name属性可读可写 { get { returnstuName; } set { stuName=value; } }66//将SetCourse设为静态方法,是因为它仅访问静态数据域//不需要创建Student类对象就可直接用Student类名调用//它的形参是一个参数数组,这样调用时就可根据实际选修的课程数来设置 publicstaticvoidSetCourse(paramsCourse[]topic) { for(inti=0;i<topic.Length;i++) { list[i].Name=topic[i].Name; list[i].Mark=topic[i].Mark; } }//AddData方法将一个学生的数据添加到学生类对象数组中publicvoidAddData(stringname,stringId,int[]score){ stuName=name; stuID=Id; for(inti=0;i<score.Length;i++) stuScore[i]=score[i];}67 //根据课程的学分以及学生成绩计算GPA
publicvoidComputeGPA() { inti; doublesMark,sumMark=0,sumGP=0; for(i=0;i<stuScore.Length;i++) { if(stuScore[i]>=95) sMark=4.5; elseif(stuScore[i]>=90)sMark=4; elseif(stuScore[i]>=85)sMark=3.5; elseif(stuScore[i]>=80)sMark=3; elseif(stuScore[i]>=75)sMark=2.5; elseif(stuScore[i]>=70)sMark=2; elseif(stuScore[i]>=65)sMark=1.5; elseif(stuScore[i]==60)sMark=1; else sMark=0; sumGP+=list[i].Mark*sMark; sumMark+=list[i].Mark; } stuGPA=sumGP/sumMark; }68//stuSwap方法提供两个Student类对象的交换操作,注意形参被修饰为ref publicvoidstuSwap(refStudentstu1,refStudentstu2) { stringname,Id; inti; int[]score=newint[Student.CourseNum]; doublegpa; name=stu1.Name; Id=stu1.stuID; gpa=stu1.GPA; for
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 胎儿窘迫的病因分析
- 肝病科护理信息化建设与应用
- 静脉溶栓治疗概述
- 输血治疗的监测与评估
- 2026 增肌期戒糖指导课件
- 门诊护理查房中的护理职业素养
- 骨折患者心理康复护理查房
- 肿瘤护理的核心技能
- 足部护理与运动康复
- 2026年供热管网节能改造与水力平衡
- 2026年设备出售转让合同(1篇)
- 2026年深圳市盐田区初三二模语文试卷(含答案)
- 男女病人导尿课件
- BB/T 0045-2021纸浆模塑制品工业品包装
- 抽油机常见故障2概要课件
- 药理学 治疗充血性心力衰竭的药物
- 煤化工概述-课件
- 变电工程110kV户内项目
- GB∕T 5336-2022 汽车车身修理技术条件
- 地铁通风空调施工组织设计
- 《外科学》第七节 直肠癌
评论
0/150
提交评论