java 实验5 接口多态实验报告.docx
《java 实验5 接口多态实验报告.docx》由会员分享,可在线阅读,更多相关《java 实验5 接口多态实验报告.docx(23页珍藏版)》请在冰点文库上搜索。
java实验5接口多态实验报告
实验五接口、多态与内部类
实验目标:
1、理解接口、塑型、多态的概念并能熟练应用;
2、熟练掌握接口的定义和使用;
3、深刻理解构造方法的调用顺序,理解编写时需要注意的问题;
4、了解并学会使用内部类
实验任务:
1、继承时的多态:
目测给出下面代码的执行输出结果,并简单解释每一行输出的原因。
答:
首先,该程序的主函数是Vehiclev=newVehicle();即先声明并实例化一个汽车对象,而v.test();则是调用汽车的测试方法;而test方法里,Vehiclevc=newCar();是将上面的汽车指向了一个具体的小汽车对象;Busvb=newBus();将公共汽车指向了一个具体的公共汽车对象;drive();调用汽车的驾驶方法;vc.drive();调用小汽车的驾驶方法;vb.drive();调用公共汽车的驾驶方法;而vc.brake();vb.brake();则是直接调用汽车的刹车方法。
因而运行结果如下:
Anewbus.
Vehicleisdriven
Carisdriven
Busisdriven
Vehicleisbraked
Vehicleisbraked
2.针对下面的简单的类图,从面向对象的角度,将Instrument定义成接口,应怎样实现。
编写能完成如图功能的程序,并再编写一个简单的应用程序进行多态性测试。
(参考例子5-9;实验4该题是要求用抽象类来实现,在此要求用接口实现,还要进行多态性测试)
说明:
Instrument表示乐器、Wind表示管乐器、Percussion敲击乐器、Stringed表示弦乐器、Woodwind表示木管乐器、Brass表示铜管乐器。
要求:
(1)Instrument为接口,Wind为抽象类,其他为普通类。
这里测试的目的是:
我们知道当一个普通类实现一个接口时,必须实现该接口的全部方法,但当这个类是抽象类时,我们还需要实现该接口全部方法吗?
如果不需要实现?
那么是否直接不理这个方法就一,还是要将这个方法在自己类内部再标记一次为抽象方法。
(听起来有点晕,测试很简单的,有时百读不如一试)
(2)请编写测试代码,对实现Instrument接口的各个类进行多态测试,具体可参考课本例子。
所谓多态测试就是向上自动塑型,以及向下动态绑定,而动态绑定的基本规则是实例方法“由下往上”寻找绑定,类方法和类属性成员“由上往下”寻找绑定。
(对其概念不清晰的请留意课本知识与课堂讲解)
该题代码如下:
packagezi;
interfaceInstrument{
voidplay();
Stringwhat();
voidadjust();
}
abstractclassWindimplementsInstrument{
publicvoidplay(){
System.out.println("Wind.play()");
}
publicabstractStringwhat();
publicvoidadjust(){
System.out.println("Wind.adjust");
}
}
classPercussionimplementsInstrument{
publicvoidplay(){
System.out.println("Percussion.play()");
}
publicStringwhat(){
return"Percussion.play()";
}
publicvoidadjust(){
System.out.println("Percussion.adjust()");
}
}
classStringedimplementsInstrument{
publicvoidplay(){
System.out.println("Stringed.play()");
}
publicStringwhat(){
return"Stringed.play()";
}
publicvoidadjust(){
System.out.println("Stringed.adjust()");
}
}
classBrassextendsWind{
publicvoidplay(){
System.out.println("Brass.play()");
}
publicStringwhat(){
return"Brass.play()";
}
publicvoidadjust(){
System.out.println("Brass.adjust()");
}
}
classWoodwindextendsWind{
publicvoidplay(){
System.out.println("Woodwind.play()");
}
publicStringwhat(){
return"Woodwind.play()";
}
publicvoidadjust(){
System.out.println("Woodwind.adjust()");
}
}
publicclassEx5_2{
publicstaticvoidmain(String[]args){
Instrumenti2,i3,i4,i5;
//i1=newWind();
//i1.play();
i2=newPercussion();
i2.play();
i3=newStringed();
i3.play();
i4=newBrass();
i4.play();
i5=newWoodwind();
i5.play();
}
}
其执行结果如下图所示:
该程序的uml图截图如下:
3.编写程序,要求如下:
(1)定义Biology(生物)、Animal(动物)和Mankind(人)3个接口;
该题代码截图如下:
以下为Biology(生物)的接口:
以下为Animal(动物)的接口:
以下为Mankind(人)的接口:
(2)接口Biology声明breath()抽象方法;
截图如下:
(3)接口Animal继承Biology并声明move()和eat()抽象方法;
其代码如下:
interfaceAnimalsextendsBiology{
voidbreathe();
voideat();
voidmove();
}
(4)接口Mankind继承Animal并声明study()和think()抽象方法,增加属性MaxAge;
其代码如下:
packagezi;
interfaceBiology{
voidbreath();
}
interfaceAnimalextendsBiology{
voidmove();
voideat();
}
publicinterfaceMankindextendsAnimal{
intMaxAge=150;
voidstudty();
voidthink();
}
其UML图截图如下:
(5)定义类Man和Woman实现接口Mankind,实现它们声明的抽象方法,并增加属性,name,sex(类属性成员)和age;(具体实现可以只显示相应的提示信息就可以,如同书本例子一样);
(6)在类Man和Woman中实现无参构造方法和有参构造方法两种不同的构造方法,有参构造方法输入自己姓名,自己年龄,在构造方法中如果年龄超出MaxAge则输出出错信息并修改成默认年龄。
(7)编写测试类使用接口Mankind来测试类Man和Woman的多态性。
(向上塑型和向下动态绑定)
以上三小问的程序如下所示:
packagezi;
publicinterfaceMankindextendsAnimal{
intMaxAge=150;
voidstudy();
voidthink();
}
packagezi;
publicclassManimplementsMankind{
protectedStringname;
staticStringsex="male";
protectedintage;
publicMan(){
this("某男",18);
}
publicMan(Stringname,intage){
this.name=name;
if((age<=MaxAge)&&(age>0)){
this.age=age;
}else{
System.out.println("AgeWrong,Init18");
this.age=18;
}
}
@Override
publicvoidmove(){
//TODO自动生成的方法存根
System.out.println("Man'smove");
}
@Override
publicvoideat(){
//TODO自动生成的方法存根
System.out.println("Man'seat");
}
@Override
publicvoidbreath(){
//TODO自动生成的方法存根
System.out.println("Man'sbreath");
}
@Override
publicvoidstudy(){
//TODO自动生成的方法存根
System.out.println("Man'sstudy");
}
@Override
publicvoidthink(){
//TODO自动生成的方法存根
System.out.println("Man'sthink");
}
publicStringtoString(){
return(name+","+sex+","+age);
}
}
packagezi;
publicclassWomanimplementsMankind{
protectedStringname;
staticStringsex="female";
protectedintage;
publicWoman(){
this("某女",18);
}
publicWoman(Stringname,intage){
this.name=name;
if((age<=MaxAge)&&(age>0)){
this.age=age;
}else{
System.out.println("AgeWrong,Init18");
this.age=18;
}
}
@Override
publicvoidmove(){
//TODO自动生成的方法存根
System.out.println("Woman'smove");
}
@Override
publicvoideat(){
//TODO自动生成的方法存根
System.out.println("Woman'seat");
}
@Override
publicvoidbreath(){
//TODO自动生成的方法存根
System.out.println("Woman'sbreath");
}
@Override
publicvoidstudy(){
//TODO自动生成的方法存根
System.out.println("Woman'sstudy");
}
@Override
publicvoidthink(){
//TODO自动生成的方法存根
System.out.println("Woman'sthink");
}
publicStringtoString(){
return(name+","+sex+","+age);
}
}
packagezi;
publicclassEx5_3{
publicstaticvoidmain(String[]args){
Mankindm1=newMan("张男",-2);
Mankindm2=newWoman("李女",180);
System.out.println(m1.toString());
System.out.println(m2.toString());
m1.breath();
m2.breath();
m1.move();
m2.move();
m1.study();
m2.study();
m1.think();
m2.think();
}
}
其UML图如下图所示:
4.在第4章课后习题10的基础上(也是实验04的实验题),声明测试类完成对多态性的测试,具体要求请参见课本171页第5章课后习题8。
该题的测试类的代码如下:
packagezi;
importjava.text.*;
publicclassEx5_4{
publicstaticvoidmain(Stringargs[]){
Studentstudent[]={
newStudent("2012001","张三",76.00f,80.00f,94.00f),
newStudent("2012002","李四",81.00f,85.00f,80.00f),
newStudent("2012003","王五",91.00f,77.00f,75.00f),
newStudentXW("2012004","林六",98.00f,87.00f,36.00f,"英语代表"),
newStudentBZ("2012005","赵七",94.00f,85.00f,87.00f,"班长")
};
for(inti=0;i<5;i++)
{
System.out.println("学生名字:
"+student[i].getname()+"\t评测成绩:
"+newDecimalFormat("0.00").format(student[i].testScore()));
}
}
}
其运行结果如下:
该程序的UML图截图如下:
5、内部类:
定义一个类Outer,类中拥有私有成员变量a和成员方法output()。
在这个类中定义一个内部类Inner,内部类中定义一个方法out()修改外部类的成员变量a的值,并调用外部类的私有方法output()。
最后在外部类的公有静态main方法中调用内部类的方法。
要求:
测试使用两种方式来调用内部类方法,
第一种,在外部类方法里面创建内部类对象,在main方法里面通过调用外部类的方法来间接调用内部类方法;
该题代码如下:
packagezi;
publicclassOuter1{
privateStringa;
publicvoidoutput(){
System.out.println(a);
}
classInner{
publicInner(){
}
publicvoidout(Stringb){
a=b;
output();
}
}
publicvoidrun(){
Inneri1=newInner();
i1.out("aofOuter1changedbyInner");
}
publicstaticvoidmain(Stringargs[]){
Outer1o1=newOuter1();
o1.run();
}
}
其运行结果如下图所示:
其UML图截图如下:
第二种,在main方法里面直接创建内部类对象,直接调用内部类方法
该题代码如下:
packagezi;
publicclassOuter2{
privateStringa;
publicvoidoutput(){
System.out.println(a);
}
classInner{
publicInner(){
}
publicvoidout(Stringb){
a=b;
output();
}
}
publicvoidrun(){
Inneri1=newInner();
i1.out("abcdefg");
}
publicstaticvoidmain(Stringargs[]){
Outer2o2=newOuter2();
Outer2.Innerii1=o2.newInner();
ii1.out("aofOuter2byInner");
}
}
其执行结果图下图所示:
该程序的UML图截图如下:
6、(选做)匿名内部类:
内部类可以声明在方法内部,甚至以匿名的形式声明在new关键字后,试着填充下面的代码,实现匿名的内部类。
填充后代码如下:
packagezi;
importjava.util.Observable;
importjava.util.Observer;
publicclassEx5_6extendsObservable{
Stringinfo="";
publicEx5_6(Stringinfo){
this.info=info;
this.addObserver(newObserver(){
publicvoidupdate(Observablea,Objectb){
System.out.println("Observer2updatedfor<"+Ex5_6.this.info+">");
}
});
this.addObserver(newObserver(){
publicvoidupdate(Observablearg0,Objectarg1){
System.out.println("Observer1updatedfor<"+Ex5_6.this.info+">");
}
});
}
publicstaticvoidmain(String[]args){
Ex5_6obs=newEx5_6("MyMyObservable");
obs.setChanged();
obs.notifyObservers();
}
}
其运行结果截图如下:
该程序的UML图截图如下:
实验心得:
本次实验量比较少,而且老师为部分题目做了实验演示,所以我们完成实验报告时没之前那么费力。
通过本次实验,我更加深入了解接口、塑型和多态的定义,并且能根据题目要求将其运用。
除此之外,我还更加深刻理解构造方法的调用顺序以及我们在编写程序时必须要注意的问题,能够学以致用。