实验6继承与接口.docx

上传人:b****4 文档编号:4075115 上传时间:2023-05-06 格式:DOCX 页数:21 大小:195.39KB
下载 相关 举报
实验6继承与接口.docx_第1页
第1页 / 共21页
实验6继承与接口.docx_第2页
第2页 / 共21页
实验6继承与接口.docx_第3页
第3页 / 共21页
实验6继承与接口.docx_第4页
第4页 / 共21页
实验6继承与接口.docx_第5页
第5页 / 共21页
实验6继承与接口.docx_第6页
第6页 / 共21页
实验6继承与接口.docx_第7页
第7页 / 共21页
实验6继承与接口.docx_第8页
第8页 / 共21页
实验6继承与接口.docx_第9页
第9页 / 共21页
实验6继承与接口.docx_第10页
第10页 / 共21页
实验6继承与接口.docx_第11页
第11页 / 共21页
实验6继承与接口.docx_第12页
第12页 / 共21页
实验6继承与接口.docx_第13页
第13页 / 共21页
实验6继承与接口.docx_第14页
第14页 / 共21页
实验6继承与接口.docx_第15页
第15页 / 共21页
实验6继承与接口.docx_第16页
第16页 / 共21页
实验6继承与接口.docx_第17页
第17页 / 共21页
实验6继承与接口.docx_第18页
第18页 / 共21页
实验6继承与接口.docx_第19页
第19页 / 共21页
实验6继承与接口.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

实验6继承与接口.docx

《实验6继承与接口.docx》由会员分享,可在线阅读,更多相关《实验6继承与接口.docx(21页珍藏版)》请在冰点文库上搜索。

实验6继承与接口.docx

实验6继承与接口

山西大学计算机与信息技术学院

实验报告

姓名

学号

专业班级

课程名称

Java实验

实验日期

成绩

指导教师

批改日期

实验名称

实验6继承与接口

[实验目的]

1、掌握java继承中父类及其子类的定义方法。

2、掌握子类重写父类同名方法的方法。

3、掌握接口的用法。

(1)学习如何定义接口;

(2)掌握接口的实现方式;

(3)使用实现了接口的类;

(4)理解接口与抽象类的区别。

[实验要求]

1、复习理论教学中所学的内容。

2、认真进行实验预习,查阅参考书,书写源程序,书写实验预习报告。

3、认真总结实验并书写实验报告。

[实验内容]

1、类的继承性练习

(1)程序源代码如下。

publicclassStudent{

protectedStringxm;//姓名,具有保护修饰符的成员变量

protectedintxh;//学号

voidsetdata(Stringxm,intxh){//设置数据的方法

this.xm=xm;

this.xh=xh;

}

publicvoidprint(){//输出数据的方法

System.out.println(xm+","+xh);

}

}

classTestStudent{//测试类

publicstaticvoidmain(String[]args){

Students=newStudent();

s.setdata("小红",2010242555);

s.print();

}

}

(2)编译源并运行程序。

贴图如下

图一

(二)创建将被继承的类

(1)程序功能:

通过Student类产生子类CollegeStudent,其不仅具有父类的成员变量xm(姓名)、xh(学号),还定义了新成员变量xy(学院)、bj(bj)。

在程序中调用了父类的print方法,同时可以看出子类也具有该方法。

程序代码:

publicclassCollegeStudentextendsStudent{

protectedStringxy;

protectedintbj;

voidsetdata(Stringxm,intxh,Stringxy,intbj){

super.setdata(xm,xh);

this.xy=xy;

this.bj=bj;

}

publicvoidprint(){

super.print();

System.out.print("学院:

"+xy+"班级:

"+bj);

}

}

classTestCollegeStudent{

publicstaticvoidmain(String[]args){

CollegeStudentcs=newCollegeStudent();

cs.setdata("小蓝",2010242555,"计算机学院",1);

cs.print();

}

}

运行结果贴图:

图二

(三)了解成员方法的覆盖方式

(1)编写覆盖了Object类toString方法的一个类,并用System.out.println()输出该类的一个对象。

程序代码:

publicclassOverWriteToString{

privateStringstr;

publicOverWriteToString(){

}

publicOverWriteToString(Stringstr){

this.str=str;

}

publicStringToString(){

returnsuper.toString()+"\n"+str;

}

publicstaticvoidmain(String[]args){

OverWriteToStringo=newOverWriteToString("Thisisamethod"

+"tooverwriteToStringmethod!

");

System.out.println(o.ToString());

}

}

运行结果贴图:

图三

(2)试着以Point类为例,尝试为Object类的clone()和equals()方法进行覆盖,Point类包含私有成员x,y,构造方法1(包含两个参数a,b),构造方法2(参数为Pointp),clone方法,equals方法,toString方法。

用TestPoint类进行测试。

程序代码:

publicclassPoint{

privateintx;

privateinty;

publicPoint(){

}

publicPoint(inta,intb){

x=a;

y=b;

}

publicPoint(Pointp){

x=p.x;

y=p.y;

}

//重写equals()方法

publicbooleanequals(Objecto){

if(oinstanceofPoint){

return(x==((Point)o).x&&y==((Point)o).y);

}

else

returnfalse;

}

//重写toString()方法

publicStringtoString(){

returnsuper.toString()+"\n该点的坐标为("+x+","+y+")";

}

//重写clone()方法

publicObjectclone()throwsCloneNotSupportedException{

returnnewPoint(this);

}

}

classTestPoint{

publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{

Pointp=newPoint(2,3);

Pointp1=newPoint(p);

Pointp2=(Point)p.clone();

System.out.println("p与p1相等吗?

"+p.equals(p1));

System.out.println("p与p2相等吗?

"+p.equals(p2));

System.out.println(p);

System.out.println(p1);

System.out.println(p2);

}

}

运行结果贴图:

图四

(四)this、super和super()的使用

(1)程序功能:

说明this、super和super()的用法。

程序首先定义Point(点)类,然后创建点的子类Line(线)。

最后通过TestLine类输出线段的长度。

程序中通过super(a,b)调用父类Point的构造方法为父类的x和y赋值。

在子类Line的setLine方法中,因为参数名和成员变量名相同,为给成员变量赋值,使用this引用,告诉编译器是为当前类的成员变量赋值。

在length和toString方法中使用父类成员变量时,使用super引用,告诉编译器使用的是父类的成员变量。

程序代码:

publicclassLineextendsPoint{

privatePointp1;

privatePointp2;

publicLine(){

super(5,5);

}

publicLine(intx1,inty1,intx2,inty2){

super(5,5);

p1=newPoint(x1,y1);

p2=newPoint(x2,y2);

}

publicLine(Pointp1,Pointp2){

super(5,5);

this.p1=p1;

this.p2=p2;

}

publicvoidsetLine(Pointp1,Pointp2){

this.p1=p1;

this.p2=p2;

}

publicdoublelegth(){

returnMath.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));

}

publicStringtoString(){

returnsuper.toString()+"\n该线起点为:

("+p1.x+","+p1.y+")"

+"终点为:

("+p2.x+","+p2.y+")";

}

}

classTestLine{

publicstaticvoidmain(String[]args){

Pointp1=newPoint();

Pointp2=newPoint(3,4);

Linel=newLine(p1,p2);

System.out.println("线l的长度为:

"+l.legth());

System.out.println(l);

}

}

运行结果贴图:

图五

(五)接口的实现与运用

实验任务:

本实验的任务是设计和实现一个Soundable接口,该接口具有发声功能,同时还能够调节声音大小。

Soundable接口的这些功能将会由3种声音设备来具体实现,它们分别是收音机Radio、随身昕Walkman和手机Mobilephone。

最后还要设计一个应用程序类来使用这些实现了Soundable接口的声音设备类。

程序运行时,先询问用户想听哪种设备,然后程序就会按照该设备的工作方式来发出声音。

实验步骤:

(1)仔细阅读程序,并完成其中的代码1~代码3。

//InterfaceTest.java

importjava.util.*;

interfaceSoundable{

publicvoidincreaseVolume();

publicvoiddecreaseVolume();

publicvoidstopSound();

publicvoidplaySound();

}

classRadioimplementsSoundable{

publicvoidincreaseVolume(){

System.out.println("增大收音机音量");

}

publicvoiddecreaseVolume(){

System.out.println("减小收音机音量");

}

publicvoidstopSound(){

System.out.println("关闭收音机");

}

publicvoidplaySound(){

System.out.println("收音机播放广播");

}

}

classWalkmanimplementsSoundable{

publicvoidincreaseVolume(){

System.out.println("增大随声听音量");

}

publicvoiddecreaseVolume(){

System.out.println("减小随声听音量");

}

publicvoidstopSound(){

System.out.println("关闭随声听");

}

publicvoidplaySound(){

System.out.println("随声听播放音乐");

}

}

classMobilePhoneimplementsSoundable{

publicvoidincreaseVolume(){

System.out.println("增大手机音量");

}

publicvoiddecreaseVolume(){

System.out.println("减小手机音量");

}

publicvoidstopSound(){

System.out.println("关闭手机");

}

publicvoidplaySound(){

System.out.println("手机播放铃声");

}

}

classPeople{

privateStringname;

privateintage;

publicvoidListen(Soundables){

s.playSound();

}

}

publicclassInterfaceTest{

publicstaticvoidmain(String[]args){

inti;

Peoplesportsman=newPeople();

Scannerinput=newScanner(System.in);

Soundable[]soundDevice=newSoundable[3];

soundDevice[0]=newRadio();

soundDevice[1]=newWalkman();

soundDevice[2]=newMobilePhone();

System.out.println("你想听什么?

请输入选择(0——收音机,1——随声听,2——手机):

");

i=input.nextInt();

sportsman.Listen(soundDevice[i]);

soundDevice[i].increaseVolume();

soundDevice[i].stopSound();

}

}

(2)打开文本编辑器编辑InterfaceTest.java并保存,然后在Eclipse环境中进行编译,编译的结果将会产生6个class文件,其中包括Soundable.class,虽然Soundable本身是一个接口,但编译之后也会产生class文件。

(3)编译之后运行这个程序,观察所得结果。

图六

思考

(1)请问在InterfaceTest类中,SoundDevice[]数组是什么类型的,该数组为什么能存放3种不同的对象Radio、Walkman和Mobilephone呢?

答:

SoundDevice[]数组是接口类型;因为类Radio、Walkman和Mobilephone都实现了接口SoundDevice,则接口SoundDevice就类似于这三个类的父类,而父类的引用可以指向一个子类的对象,所以该数组可以存放三个不同的对象。

(2)在程序中,Soundable是一个接口,那么该接口是否可以被实例化呢?

请在InterfaceTest类的main()方法中加入以下语句试验一下,并分析结果。

SoundableSound=newSoundable(),

图七

答:

不可以。

因为接口和抽象类相似,可以声明引用类型的变量,但不可使用new操作符创建接口的实例对象。

(3)现在假定要为程序增加一个闹钟类Clock,该类也实现Soundable接口,能够发出滴答声,请将以下的Clock类加入到InterfaceTest.java程序中,并在InterfaceTest类的main()方法中加入SoundDevice[3]=newClock();语句。

classClockimplementsSoundable{

publicvoidstopSound(){

System.out.println("关闭闹钟");

}

publicvoidplaySound(){

System.out.println("闹钟发出滴答声");

}

}

修改之后,重新编译InterfaceTest.java并运行它,观察结果。

图八

(4)在第(3)小题中由于新加入的Clock类仅仅实现了Soundable接口的stopsound()和playsound()方法,而increaseVolume()和decreaseVolume()方法没有实现,因此它实质上是一个抽象类,而抽象类是不能实例化的,所以导致编译错误。

但是按照常理,闹钟的滴答声确实是不可以增大或减小的,那么如何解决这个问题呢?

现在请在Clock类中加入下面两个含{}空方法体的方法实现,再编译运行程序,看看会有什么变化。

publicvoidincreaseVolume(){}

publicvoiddecreaseVolume(){}

图九

(5)现在请模仿本实验的程序设计出一个自己的接口程序,要求先设计一个moveable可移动接口,然后分别设计3个类,即汽车Car、轮船Ship、飞机Aircraft来实现该接口,最后设计一个应用程序来使用它们。

程序代码:

importjava.util.*;

interfaceMoveable{

publicabstractvoidmove();

}

classCarimplementsMoveable{

publicvoidmove(){

System.out.println("汽车行驶");

}

}

classShipimplementsMoveable{

publicvoidmove(){

System.out.println("轮船航行");

}

}

classAircraftimplementsMoveable{

publicvoidmove(){

System.out.println("飞机飞行");

}

}

publicclassTestMoveable{

publicstaticvoidmain(String[]args){

Scannerinput=newScanner(System.in);

Moveable[]moveDevice=newMoveable[3];

moveDevice[0]=newCar();

moveDevice[1]=newShip();

moveDevice[2]=newAircraft();

System.out.println("您想乘坐什么?

请输入选择(0——汽车,1——轮船,2——飞机):

");

inti=input.nextInt();

Moveablem=moveDevice[i];

m.move();

input.close();

}

}

运行结果贴图:

图十

实验分析:

接口的特点在于只定义能做什么,而不定义怎么去做。

在本实验中,收音机Radio,随身听Walkman和手机Mobilephone分别以自己的方式实现了Soundable接口,当接口成为Listen(Soundables)方法的形参时,任何实现了Soundable接口的对象都能成为它的实参,如果不用接口作形参,那就必须写3个不同的方法,即

listenRadio(Radior),

listenWalkman(Walkmanw),

listenMobilephone(Mobilephonem)。

课后作业题:

题11.1

图a的输出结果:

体现了构造方法链

图十一

图b编译问题:

父类构造方法并未被子类继承,当父类构造方法带形参时,在子类构造方法中应显示传递父类构造方法所需参数,且使用关键字super调用父类方法;

图十二

解决方法:

classA{

publicA(intx){

}

}

classBextendsA{

publicB(intx){

super(x);

}

}

publicclassC{

publicstaticvoidmain(String[]args){

Bb=newB

(2);

}

}

图十三

题11.3

代码错误:

1.构造方法初始化类数据域时,由于参数名与数据域名相同,故数据域在构造方法中被隐藏,使用时应用关键字this来引用;

2.父类的构造方法是不被子类继承的,只能在子类的构造方法中使用关键字super调用;

3.调用父类中被覆盖的方法应使用关键字super来应用。

解决方法:

publicclassCircle{

privatedoubleradius;

publicCircle(doubleradius){

this.radius=radius;

}

publicdoublegetRadius(){

returnradius;

}

publicdoublegetArea(){

returnradius*radius*Math.PI;

}

}

classBextendsCircle{

privatedoublelength;

B(doubleradius,doublelength){

super(radius);

this.length=length;

}

publicdoublegetArea(){

returnsuper.getArea()*length;

}

}

classTestCircle{

publicstaticvoidmain(String[]args){

Bb=newB(2,3);

System.out.println("半径为:

"+b.getRadius());

System.out.println("面积为:

"+b.getArea());

}

}

图十三

题11.5

如何在子类调用被覆盖的父类方法:

使用关键字super调用。

题11.7

如果子类中的一个方法具有和它父类中的方法完全相同的方法头,且返回值类型也相同,那么这是方法的覆盖。

题11.9

如果子类中的一个方法具有和它父类中的方法相同的名字,但参数类型不同,那么这是方法的重载。

题11.13

(1)true

(2)false(3)true(4)true(5)false(6)true(7)true(8)

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2