实验8继承与多态Read.docx
- 文档编号:14611753
- 上传时间:2023-06-25
- 格式:DOCX
- 页数:20
- 大小:25.17KB
实验8继承与多态Read.docx
《实验8继承与多态Read.docx》由会员分享,可在线阅读,更多相关《实验8继承与多态Read.docx(20页珍藏版)》请在冰点文库上搜索。
实验8继承与多态Read
实验8继承与多态
8.1实验目的
(1)理解类的继承,掌握变量隐藏、方法覆盖的概念。
(2)理解引用类型的变量的赋值转换原则。
(3)理解多态概念,掌握方法的匹配调用原则;
(4)理解抽象类与接口的使用;
(5)理解this和super的含义及使用。
(6)理解访问控制符的使用
8.2知识要点
8.2.1继承的概念
通过类的继承,祖先类的所有成员均将成为子类拥有的“财富”。
但是能否通过子类对象直接访问这些成员则取决于访问权限设置。
Object类是所有类的祖先。
8.2.2构造方法与继承关系
构造方法不存在继承关系,子类中是如何给父类继承的属性赋初值呢?
子类通过调用父类的构造方法给父类的属性赋值,在子类的构造方法的第1行可以通过super去调用父类的构造方法,如果没有super调用,则默认调用父类的无参构造方法。
所以,在父类中编写构造方法通常均要提供无参构造方法。
8.2.3 对象引用变量赋值原则
可以将子类的对象引用赋值给父类引用变量,由于父类能操作访问属性和方法的子类已全部继承。
但将父类引用变量的值赋给子类引用变量就受到限制,必须进行强制转换,编译总是认可强制转换,但运行程序时如果不能正确转换就会报错。
8.2.4多态的两种表现形式
(1)同一类中的方法多态(方法重载):
同一类中允许多个同名方法,通过参数的数量、类型的差异进行区分。
(2)子类对父类方法的重新定义(方法覆盖):
方法名、返回值和参数形态完全一样。
(3)方法调用的匹配原则。
首先查找有否有参数一致的方法,也就是精确匹配;如果没有,再检查实参是否能自动转换为形参类型,能转换也可以匹配调用,这种匹配称为转换匹配。
8.2.5 继承关系中对成员的访问(最近匹配原则)
由于继承关系的存在,一个对象的属性和方法中有自己新定义的,也有从祖先类继承的。
允许子类对父类定义的属性和方法重新定义,一个对象查找其属性和方法时按什么原则查找呢,实际也是“最近匹配原则”。
(1)在子类中访问属性和方法时将优先查找自己定义的属性和方法。
如果该成员在本类存在,则使用本类的,否则,按照继承层次的顺序到其祖先类查找,如图8-1所示。
(2)this关键字特指本类的对象引用,使用this访问成员则首先在本类中查找,如果没有,则到父类逐层向上找。
(3)super特指访问父类的成员,使用super首先到直接父类查找匹配成员,如果未找到,再逐层向上到祖先类查找。
8.2.6抽象类
定义形式:
abstractclass类名称{
成员变量;
方法(){……} //定义一般方法
abstract方法();//定义抽象方法
}
● 在抽象类中可以包含一般方法和抽象方法。
● 抽象类表示的是一个抽象概念,不能被实例化为对象。
● 继承抽象类的具体类必须将抽象类中抽象方法覆盖实现。
8.2.7接口
(1)接口定义
[public]interface接口名[extends父接口名列表] {
域类型域名=常量值;//常量域声明
返回类型方法名(参数列表)[throw异常列表];//抽象方法声明
}
● 接口只包括常量定义和抽象方法。
● 接口具有继承性,一个接口还可以继承多个父接口,父接口间用逗号分隔。
● 系统默认,接口中所有属性的修饰都是publicstaticfinal,也就是静态常量;
● 系统默认,接口中所有方法的修饰都是publicabstract。
(2)接口实现(implements)
接口定义了一套行为规范,一个类实现这个接口就要遵守接口中定义的规范,实际上就是要实现接口中定义的所有方法。
● 一个类可以实现多个接口;
● 类中实现接口的方法要加public修饰,因为接口中定义的抽象方法默认为public。
8.3样例程序
样例1:
设计一个类层次,定义一个抽象类--形状,其中包括有求形状的面积的抽象方法。
继承该抽象类定义三角型、矩形、圆。
分别创建一个三角形、矩形、圆存入一个数组中,将数组中各类图形的面积输出。
注:
三角形面积s=sqrt(p*(p-a)*(p-b)*(p-c))其中,a,b,c为三条边,p=(a+b+c)/2
【参考程序】
abstractclassShape{
abstractpublicdoublearea();
}
classTriangleextendsShape{
privatedoublea,b,c;
publicTriangle(doublea,doubleb,doublec){
this.a=a;this.b=b;this.c=c;
}
publicdoublearea() {
doublep=(a+b+c)/2;
returnMath.sqrt(p*(p-a)*(p-b)*(p-c));
}
}
classRectangleextendsShape{
privatedoublewidth,height;
publicRectangle(doublej,doublek){
width=j;height=k;
}
publicdoublearea()
{
returnwidth*height;
}
}
classCircleextendsShape{
privatedoubler;
publicCircle(doubler){
this.r=r;
}
publicdoublearea(){
return3.14*r*r;
}
}
publicclassCount{
publicstaticvoidmain(Stringargs[]) {
Shapes[]=newShape[3];
s[0]=newTriangle(22,41,57);
s[1]=newRectangle(17,17);
s[2]=newCircle(47);
for(intz=0;z System.out.println(s[z].area()); } } 【编程技巧】 (1) 抽象类定义的方法在具体类要实现; (2) 使用抽象类的引用变量可引用子类的对象; (3) 通过父类引用子类对象,通过该引用访问对象方法时实际用的是子类的方法。 可将所有对象存入到父类定义的数组中。 样例2: 定义接口Shape,其中包括一个方法size(),设计“直线”、“圆”、“会议”、“圆柱体”等类实现Shape接口。 分别创建一个“直线”、“圆”、“会议”、“圆柱体”存入一个数组中,将数组中各类图形的大小输出。 注: 圆柱体可考虑由底边圆和高度两个部分组成。 【参考程序】 interfaceShape{ doublesize(); } classLineimplementsShape{ privatedoublex1,y1,x2,y2; publicLine(doublex1,doubley1,doublex2,doubley2){ this.x1=x1;this.y1=y1; this.x2=x2;this.y2=y2; } publicdoublesize() { returnMath.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } } classCircleimplementsShape{ privatedoubler; publicCircle(doubler){ this.r=r; } publicdoublesize(){ return3.14*r*r; } } classConferenceimplementsShape{ privatedoublepeoples; public Conference(doublep){ peoples=p; } publicdoublesize(){ returnpeoples; } } class圆柱体implementsShape{ privateCirclec; privatedoubleh; public圆柱体(Circlec1,doubleh1){ c=c1;h=h1; } publicdoublesize(){ returnc.size()*h; } } publicclassCount{ publicstaticvoidmain(Stringargs[]) { Shapes[]=newShape[4]; s[0]=newLine(22,56,41,57); s[1]=newCircle(47); s[2]=newConference(247); s[3]=new圆柱体(newCircle(20),4); for(intz=0;z System.out.println(s[z].size()); } } 【编程技巧】 (1)接口中定义的方法在实现接口的具体类中要重写实现; (2)利用接口类型的变量可引用实现该接口的类创建的对象。 8.4上机练习 ✧ 基本题 1)方法调用匹配测试 class methodMatch{ doublex=5,y=6; voidtest(doubley){ System.out.println(y); test(this); //转换匹配哪个方法 } publicStringtoString(){ returnx+","+y; } void test(String a){ System.out.println(a); } void test(Object a){ System.out.println(a); } publicstaticvoidmain(Stringargs[]){ methodMatch a=new methodMatch(); a.test(8); a.test("hello"); } } 分析以上程序运行结果,删除test(String)方法后结果如何? 加入一个test(int)方法执行结果又如何? 最后,总结方法调用的匹配原则。 2)定义一个接口,其中包含一个display()方法用于显示信息;通知类、汽车类、广告类均要实现该接口显示“通知内容”,“汽车油量”,“广告消息”。 试编程实现并测试该模型。 创建的对象用接口引用,并执行接口的display()方法。 ✧ 提高题 1)分别下面程序中x的访问权限进行修改,测试访问许可。 修改包括: private,protected,public以及无访问控制符4种情形。 程序1: 同一类情形(文件accessTest.java) packagetest class accessTest{ staticintx=8; publicstaticvoidmain(Stringargs[]){ Sysstem.out.println(x); } } 程序2: 同一包情形(文件samePackage.java) packagetest class accessTest{ staticintx=8; } classsamePackage{ publicstaticvoidmain(Stringargs[]){ Sysstem.out.println(accessTest.x); } } 程序3: 不同包的其他类情形 文件1: accessTest.java packagetest; publicclass accessTest{ staticintx=8; } 文件2: anotherPackage.java importtest.*; classanotherPackage{ publicstaticvoidmain(Stringargs[]){ Sysstem.out.println(accessTest.x); } } 程序4: 不同包的子类情形 文件1: accessTest.java packagetest; publicclass accessTest{ staticintx=8; } 文件2: subclass.java importtest.*; class subclass extends accessTest{ publicstaticvoidmain(Stringargs[]){ Sysstem.out.println(accessTest.x); } } 总结各种访问修饰符的作用。 2)编写一个程序描述以下类层次(见图8-2)。 其中人为一个抽象类,其属性包括: 姓名、性别、出生日期等。 教师包括任课学校、类别(大学、中学、小学)属性; 学生为一抽象类,其属性包括学校、学号、年级; 大学生包括专业、年级属性;中学生包括年级属性;小学生也包括年级属性。 每个类设计相应的构造方法和toString()方法,子类的toString()方法也可以调用父类的toString()方法。 在main方法中创建两个教师和8个学生对象,输出对象信息。 3)编写一个方阵类,其中封装有对方阵进行操作的方法,包括: ● 两个n阶方阵的加; ● 两个n阶方阵的减; ● 求方阵的转置矩阵; ● toString()方法按行、列描述矩阵(其中包含\n字符)。 试分别就3阶方阵和4阶方阵的数据验证类设计。 8.5思考题 1)以下程序调试结果为: classBase{ Base(){ int i=100; System.out.print(i); } } publicclassPriextendsBase{ staticinti=200; publicstaticvoidmain(Stringargv[]){ Prip=newPri(); System.out.print(i); } } A.编译错误 B.200 C.100200 D.100 (2)以下程序调试结果为: publicclassTest{ intm=5; public voidsome(intx){ m=x; } publicstaticvoidmain(Stringargs[]){ newDemo().some(7); } } classDemoextendsTest{ intm=8; public voidsome(intx){ super.some(x); System.out.println(m); } } A.5 B.8 C.7 D.无任何输出 E.编译错误 3) 试完成下述程序片段: publicclassPoint() { intx,y; public Point(intx,inty) { =x; =y; } ...... } A.Point.x Point.y B.无解 C.x1 y1 D.this.x this.y (4)考虑如下类: 1.classTest(inti){ 2. voidtest(inti){ 3. System.out.println("Iamanint."); 4. } 5. voidtest(Strings){ 6. System.out.println("Iamastring."); 7. } 8. 9. publicstaticvoidmain(Stringargs[]){ 10. Testt=newTest(); 11. charch="y"; 12. t.test(ch); 13. } 14.} 以下哪条为真? A.行5不能通过编译,方法不能被覆盖. B.行12不能通过编译,因为没有一个test()方法含字符参数. C.代码可以编译但在12行将出现异常. D.代码可以编译且产生如下输出: Iamanint. E.代码可以编译且产生如下输出: IamaString. (5)类Test1定义如下: 1.public class Test1{ 2. public float aMethod(float a,float b){ } 3. 4.} 将以下哪种方法插入行3是不合法的。 ( ) A.public float aMethod(float a,float b,float c){ } B.public float aMethod(float c,floatd){ } C.public int aMethod(int a,intb){ } D.privatefloat aMethod(inta,intb,intc){ } 6)考虑如下代码: classTree{} classPineextendsTree{} classOakextendsTree{} publicclassForest{ publicstaticvoidmain(String[]args){ Treetree=newPine(); if(treeinstanceofPine) System.out.println("Pine"); if(treeinstanceofTree) System.out.println("Tree"); if(treeinstanceofOak) System.out.println("Oak"); else System.out.println("Oops"); } } 则输出结果中有哪些? A.Pine B.Tree C.Forest D.Oops E.无输出 7)以下程序的编译和运行结果为? abstractclassBase{ abstractpublicvoidmyfunc(); publicvoidanother(){ System.out.println("Anothermethod"); } } publicclassAbsextendsBase{ publicstaticvoidmain(Stringargv[]){ Absa=newAbs(); a.amethod(); } publicvoidmyfunc(){ System.out.println("MyFunc"); } publicvoidamethod(){ myfunc(); } } A.输出结果为MyFunc B.编译指示Base类中无抽象方法 C.编译通过,但运行时指示Base类中无抽象方法 D.编译指示Base类中的myfunc方法无方法体,没谁会喜欢该方法。 8)以下程序的调试结果为? classBase{ publicfinalvoidamethod(){ System.out.println("amethod"); } } publicclassFinextendsBase{ publicstaticvoidmain(Stringargv[]){ Baseb=newBase(); b.amethod(); } } A.编译指示带有final方法的类自己必须定义为final B.编译指示不能继承含有final方法的类 C.运行错误,原因是Base类没有定义为final类 D.运行输出amethod 9)在同一目录编译和运行以下两文件结果如何? //文件P1.java packageMyPackage; classP1{ voidafancymethod(){
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 继承 Read
![提示](https://static.bingdoc.com/images/bang_tan.gif)