面向对象的高级特性.ppt_第1页
面向对象的高级特性.ppt_第2页
面向对象的高级特性.ppt_第3页
面向对象的高级特性.ppt_第4页
面向对象的高级特性.ppt_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章面向对象的高级特性,6.1.1接口的引入JAVA的单重继承机制使得程序结构简单清晰,但只靠单重继承机制有时不能解决某些复杂问题。,6.1接口,1.接口的特点:1)接口使用关键字interface来定义,而不是class2)接口中定义的变量全部是静态最终变量3)接口中没有定义构造方法,而且定义的方法都是抽象方法(只提供方法的定义,而不实现)4)接口采用多重继承机制,而不是类的单重继承机制,6.1.1接口的引入,2.接口的作用:1)用来实现类似多重继承功能的一种结构2)接口是一个标准(约定),是为了规范实现类,因此可以不用管具体实现类如何实现该接口的方法,6.1.1接口的引入,3.接口的定义:publicinterface接口名extends父接口1,父接口2,publicstaticfinaltypename1=value;publicabstract返回值类型方法名(形参表)throws异常名列表;,6.1.1接口的引入,默认的修饰符,如果没有,表示它是“友好”的,包内访问性,没有方法体,直接以分号结束,4.接口的定义举例:publicinterfaceStackpublicstaticfinalinta=1;publicabstractvoidpush(floata,floatb);publicinterfaceStack,6.1.1接口的引入,1.接口的调用方法:publicclassclassNameimplements接口名./接口中方法的具体实现,6.1.2调用接口,2.实现接口注意点:1)一个类能实现多个接口,各接口之间用逗号隔开2)一个接口可以被多个类实现3)一个类声明实现某个接口后,必须实现该接口的所有方法(包括该接口的所有父接口方法),且被实现的方法和接口定义的方法完全一样!4)被实现的方法的访问控制符必须显式地使用public修饰!,6.1.2调用接口,举例:,6.1.2调用接口,publicinterfacePlayervoidplay();voidloop();voidstop();,publicclassMyclassimplementsPlayerpublicvoidplay()/具体实现publicvoidloop();/具体实现publicvoidstop();/具体实现,当然,一个接口可以被任意多个类实现,如:,6.1.2调用接口,publicclassMyOtherclassimplementsPlayerpublicvoidplay()/具体实现.,关于接口多重继承时的实现:该类必须实现子接口和其所有父接口所定义的方法,6.1.2调用接口,publicinterfaceFirstvoidplay();,publicinterfaceSecondextendsFirstvoidstop();,classMyClassimplementsSecondpublicvoidplay()/具体实现publicvoidstop()/具体实现,注意:由于一个类实现一个接口时必须实现它的全部方法,所以在对接口进行修改时必须特别小心!,6.1.2调用接口,publicinterfacePlayervoidplay();voidloop();voidstop();voidassess();,如果新增方法定义voidassess();,则会引起所有实现这个接口的类都出错,这时候怎么修改最好?答案:为原接口定义一个子接口!,6.1.2调用接口,publicinterfacePlayerClipentendsPlayervoidassess();,接口的定义和类的定义很相似,但是,永远不能用new操作符实例化一个接口,例如:x=newPlayer();/错误!可以声明一个接口变量,并将该变量指向一个实现了该接口的类的对象,例如:Playerx=newMyclass();可以通过下面语句判断一个对象是否实现了某个接口:if(xinstanceofPlayer).,6.1.3接口的属性,接口与类相似,通过extends关键字实现继承,但是与类不一样的是,一个接口可以使用多个其他接口的内容。,6.1.4接口的扩展,publicinterfaceFourthextendsFirst,Second,注意:若两个父接口都有一个具有相同特征的方法(名字相同,参数相同),则它们必须具有相同的返回值类型!,6.1.4接口的扩展,publicinterfaceFirstintplay(inta);,publicinterfaceSecondintplay(intb);,思考:若现在要使用接口修改上次上机的程序:图形与其子类,可以怎么做?,6.1.5接口在程序中的应用,publicinterfaceShappublicabstractfloatarea();publicabstractfloatcircum();,6.1.5接口在程序中的应用,classGraphicfloatrArea;/面积floatrCircum;/周长Graphic(floata,floatc)rArea=a;rCircum=c;,classRectangleextendsGraphicimplementsShapfloatrWidth,rLong;Rectangle(floatrw,floatrl,floata,floatc)super(a,c);rWidth=rw;rLong=rl;,6.1.5接口在程序中的应用,publicfloatarea()rArea=rWidth*rLong;returnrArea;publicfloatcircum()rCircum=2*(rWidth+rLong);returnrCircum;,6.1.5接口在程序中的应用,6.2.1内部类介绍1.概念:将一个类定义在另一个类内,将此称为内部类,而包含这些内部类的类称为外部类2.内部类的声明(实例化):OuterClassouter=newOuterClass();OuterClass.InnerClassobj=outer.newInnerClass();,6.2内部类,3.内部类举例publicclassPersonintcount;publicclassStudentStringname;publicvoidoutput()System.out.print();,6.2.1内部类介绍,4.内部类的特性1)内部类的类名只能用在外部类或语句块之内。在外部引用内部类时必须给出完整的名称。如上述例子中,外部类要创建Student对象,则必须给出Person.Student2)内部类作为外部类的一个成员,如同成员变量和成员方法。在外部类中,通过一个内部类的对象引用内部类中的成员,而在内部类中可以直接引用其外部类的成员,6.2.1内部类介绍,3)外部类和内部类各有自己的成员,而且可以重名,通过不同类的对象访问不同成员4)内部类可以定义为抽象类,但需要被其它内部类继承或实现5)内部类可以是一个接口,但这个接口必须由另一个内部类实现,6.2.1内部类介绍,publicclassTest/外部类开始intb=1;publicstaticvoidmain(Stringargs)Testt=newTest();Test.Stus=t.newStu();/实例化内部类的方法b=a;/错误,不能直接引用内部类的成员System.out.println(s.getNum();/通过内部类对/象引用!,6.2.2内部类的使用,protectedclassStu/定义一个内部类,内部类的/修饰符可以是成员变量的各inta=2;/种修饰符intgetNum()returna+b;/正确,可以直接引用外部类成员/外部类结束,6.2.2内部类的使用,如果定义为private,则可见范围只在外部类之内,之外不可见,如果设计的内部类只是在某一个方法中被调用,那么可以直接把这个内部类放到该方法中,称为局部内部类局部内部类的范围总是被限定在声明他们的程序块内优点:能够对外部完全隐藏,即使外部类也不能用,6.2.3局部内部类,有时候只需要使用内部类把一个类隐藏在另一个类中,但是同时该内部类不需要对外部类的引用。这时可以把内部类声明为static,6.2.4静态内部类,6.3.1概念1.所有的对象都是通过类描绘的,但是反过来却不是,如果一个类中没有包含足够的信息来描绘一个具体的对象,把这样的类称为抽象类。抽象类往往用来表征在对问题领域进行分析、设计中得出的抽象概念。抽象类的属性和方法都是它的子类的公共属性和方法,所以改变抽象类的属性和方法一定会改变它所有子类的该属性和方法。抽象类的定义:使用abstract修饰符,6.3抽象类,例:abstractclassVehiclefloatspeed;voidstart()/bodyvoidstop()/bodyvoidacceleration()/body,6.3.1概念,floatacceleration(floata),2.以abstract修饰的方法称为抽象方法,所有的抽象方法都必须在抽象类或接口中,抽象方法只有方法头而无方法体,定义格式如下:abstract返回值类型方法名(参数表);例:abstractfloatacceleration(floata);,6.3.1概念,抽象方法是为子类定义一个共同形式上的接口,例如,在Vehicle类中可以把加速定义成抽象方法,它的子类可以用不同的方法实现加速,6.3.1概念,publicabstractclassGraphicpublicintr;abstractintarea();,6.3.1概念,classCircleextendsGraphicpublicintr;Circle(intr)this.r=r;publicintarea()return3*r*r;,classRectextendsGraphicpublicintrW,rH;Rect(intw,inth)rW=w;rH=H;publicintarea()returnrW*rH;,3.抽象类中既存在抽象方法,也存在一般方法,如果一个父类是抽象类,其非抽象子类该如何继承?,6.3.1概念,1.抽象类中一般方法的继承和普通的继承一样2.父类中抽象方法是通过覆盖实现继承,即“实现”,父类有多少抽象方法,子类就必须实现所有这些方法3.若子类没有实现所有父类抽象方法,则子类须定义为抽象类,抽象类不能有实例,但有一种情况例外:可以定义一个抽象类的对象名指向它的非抽象子类的对象例:,6.3.1概念,abstractclassSuperpublicvoida()System.out.println(“a()ofsuper”);publicabstractvoidb();,6.3.1概念,classSubextendsSuperpublicvoidb()System.out.println(“b()ofsuper”);publicvoidc()System.out.println(“c()ofsub”);,publicclassTestmain(Stringargs)Supert=newSub();t.a();t.b();t.c();/错误,既然有了抽象类,为什么还要设计接口呢?例如,可以把播放器的例子改成抽象类:,6.3.2接口和抽象类,abstractclassPlayerabstractvoidplay();abstractvoidloop();abstractvoidstop();,publicclassMyClassextendsPlayervoidplay()/bodyvoidloop()/bodyvoidstop()/body,接口和抽象类有何不同?1.从语法定义的层面看1)抽象类可以有自己的数据成员,也可以有非abstract的成员方法;而在接口中,只有静态的最终数据成员,所有的方法都是abstract的。2)从编程角度看,抽象类表示的是一种继承关系,一个类只能有单一继承;而一个类可以实现多个接口。,6.3.2接口和抽象类,接口和抽象类有何不同?2.从设计理念的层面看1)抽象类在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在“is-a”关系,即父类和派生类在概念本质上应该是相同的。2)接口不要求接口的实现者和接口定义在概念本质上是一致的,仅仅是实现了接口定义的契约而已,接口与接口实现者关系是“like-a”。,6.3.2接口和抽象类,例子:假设现在有一个关于Door的抽象概念,该Door具有执行两个动作open和close。用抽象类和接口来定义该抽象概念,可以表示如下:,6.3.2接口和抽象类,其他具体的Door类型可以extends使用抽象类方式定义的Door或者implements使用接口方式定义的Door。看起来好像使用抽象类和接口没有大的区别。,6.3.2接口和抽象类,如果现在要求Door还要具有报警的功能。该如何设计针对该例子的类结构呢?,解决方法一:,6.3.2接口和抽象类,那么具有报警功能的AlarmDoor的定义方式如下:,6.3.2接口和抽象类,classAlarmDoorextendsDoorvoidopen()voidclose()voidalarm(),classAlarmDoorimplementsDoorvoidopen()voidclose()voidalarm(),方法一有什么缺点?这种方法违反了面向对象设计中的一个核心原则ISP(InterfaceSegregationPrinciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念报警器的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为报警器这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。,6.3.2接口和抽象类,解决方法二:把Door和Alarm这两个概念都使用抽象类方式定义;两个概念都使用接口方式定义;一个概念使用抽象类方式定义,另一个概念使用接口方式定义。上述三种定义方式中,哪一种不可行?后两种方式都是可行的,应该使用哪一种?,6.3.2接口和抽象类,如果两个概念都使用接口来定义,那么AlarmDoor在概念本质上到底是Door还是报警器?这种方式未能提示事物本质。如果AlarmDoor在概念本质上是Door,同时它又具有报警的功能。我们该如何来设计以明确的反映出我们的意思呢?对于Door这个概念,我们应该使用抽象类方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过接口方式定义。,6.3.2接口和抽象类,定义方式如下:,6.3.2接口和抽象类,abstractclassDoorabstractvoidopen();abstractvoidclose();interfaceAlarmvoidalarm();classAlarmDoorextendsDoorimplementsAlarmvoidopen()voidclose()voidalarm(),1.abstractclass在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。2.在abstractclass中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是staticfinal的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。3.abstractclass和interface所反映出的设计理念不同。其实abstractclass表示的是is-a关系,interface表示的是like-a关系。4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。5.接口中定义的变量默认是publicstaticfinal型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。6.抽象类中的变量默认是friendly型,其值可以在子类中重新定义,也可以重新赋值。7.接口中的方法默认都是public,abstract类型的。,接口和抽象类小结,abstractclassSuperAbstract/父抽象类voida()System.out.println(defineda()inSuperAbstract);abstractvoidb();abstractintc(inti);interfaceAsSuper/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论