您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 第9章 抽象类和接口
Chapter9AbstractClassesandInterfaces抽象类和接口2抽象类•例:假设每个与形状有关的类都定义了display方法,用来显示具体对象的形状。ShapeRectTriangleEllipseSquareCircle此时,可以利用多态性编写代码,用来显示各种形状:Shape[]shapeBody=newShape[20];shapeBody[0]=newRect();shapeBody[1]=newShape();…for(inti=0;i20;i++){shapeBody[i].display();}3然而,由于Shape是一个抽象的概念,如果它也有display方法就不太合情理。可以做以下几种考虑:–去掉Shape类的display方法损失了多态性的优点。可能导致程序出错,如上例。–将Shape类的display方法定义成空语句publicvoiddisplay(){}–将Shape类的display方法定义成抽象方法abstractclassShape{…publicabstractvoiddisplay();}当一个类中包含了抽象的方法,此类就被认为是一个抽象类。此时Shape就不能被实例化了,从而在编译时就避免了采用第1种方法可能出现的错误。4•抽象类的特点–抽象类中的方法不一定都是抽象的,抽象类中可以包含抽象的方法,也可以包含具体的方法。–不能实例化抽象类例:如果Course是抽象类,则以下语句是错误的Coursec=newCourse();但是可以声明对Course对象的引用:Coursex;–抽象类有子类的时候,除非子类采用具体的方法替代抽象类中的全部抽象方法,否则子类本身也被自动被认为是抽象的。抽象类之所以被称之为“抽象”的,是因为抽象类省略了要执行的一种或多种特定行为的细节。5接口•接口比抽象类更抽象,它仅仅声明了方法。例如:为了教学,对象可能需要提供以下服务:–同意教授特定的课程–指定课程所使用的教科书–定义课程的授课提纲–批准特定的学生参加课程学习此时可以建立关于一个Teacher的接口:interfaceTeacher{publicvoidagreeToTeach(Coursec);publicvoiddesignateTextbook(Textbookb,Coursec);publicsyllabusdefineSyllabus(Coursec);publicbooleanapproveEnrollmen(Students,Coursec);}6有了Teacher接口,就可以把对象的各种类指定为教师例如:可以认为Professor能够教学,Student能够教学,一般的Person也可以教学:classProfessorimplementsTeacher{Stringname;StingemplyeeId;publicvoidagreeToTeach(Coursec){//编写代码}publicvoiddesignateTextbook(Textbookb,Coursec){//编写代码}publicsyllabusdefineSyllabus(Coursec){//编写代码}publicbooleanapproveEnrollmen(Students,Coursec){//编写代码}}7说明:1.通过这样的定义,Professor类替代了Teacher接口的所有方法,因此Professor类是一个具体的类。2.但是如果Professor类没有替换所有的接口,则Professor类只能看成是一个抽象的类。编译器会要求在Professor类的前面加上abstract关键字。因此,实现接口实际上就是在创建抽象类的子类时,给抽象方法“加上具体的内容”。接口与抽象类的不同在于:接口只抽象行为而抽象类则要指定属性、具体的方法和抽象的方法。8•一个类可以继承自多个接口例如:还有一个Administrator接口:interfaceAdministrator{publicbooleanapproveNewCourse(Coursec);publichireProfessor(Professorp);}则可以指定类实现Teacher和Administrator接口:classProfessorimplementsTeacher,Administrator{…}在这种情况下,类需要替代这两个接口所定义的所有方法。9•用接口实现多重继承问:为什么Java不支持多重继承?答:因为当一个子类从两个以上的父类继承下来的时候,可能会出现属性和方法重复或冲突的现象。PersonStringnameStudentStringmajorintidProfessorStringtitleStringidProfessorStudentProfessorStudent继承的属性StringnameStringmajorintidStringname(重复)StringtitleStringid(冲突)Professor可以讲课,Student类可以听课,为了描述能讲课的学生定义了ProfessorStudent类。10多重继承时方法也会发生冲突:classA{publicvoidf(){…}}classDextendsB,extendsC{publicvoidh(){f();g();}}classCextendsA{publicvoidg(){…}}classBextendsA{publicvoidg(){…}}•当在D中使用f()时,有B和C二条路径到达A中的f();•在D中调用g();时,无法确定是调用哪个基础类的g()方法11分析:1.多重继承发生问题原因之一在于属性(数据结构)冲突,也就是存储空间的冲突。由于接口不与任何存储空间相关联,因此可以解决存储空间冲突的问题。2.对于继承的方法的冲突,当使用接口之后,由于接口只定义了方法的抽象,没有具体的执行代码,因此也不会发生代码冲突的问题。12在此例中把与讲课有关的所有要素提取出来,放入Teacher接口。此时,ProfessorStudent类和Professor类都具有了讲课的能力。语句格式:classProfessorStudentextendsStudentimplementsTeacher{…}Person类Student类Professor类Teacher接口ProfessorStudent13•总结:–一个类可以继承自一个抽象类或具体类,以及多个接口。抽象类或具体类接口1接口2接口n…子类子类只有将接口中声明的所有方法,以及抽象类中所有的抽象方法都进行定义,这个子类才能成为一个“具体”的类,才能实例化。如果你的基础类可以不带任何属性和方法定义时,可以将它定义成一个接口。只有在必须带有属性和方法定义的时候,才采用抽象类或具体类。14抽象类ΔGeometricObjectCircleCylinderRectangleCircle-radius:double+getRadius():double+setRadius(radius:double):voidCylinder-length:double+getLength():double+setLength(length:double):void+findVolume():doubleGeometricObject-color:String-filled:boolean+getColor():String+setColor(Stringcolor):void+isFilled():boolean+setFilled(booleanfilled):void+findArea():double+findPerimeter():doubleObjectRectangle-width:double-length:double+getWidth():double+setWidth(width:double):void+getLength():double+setLength(length:double):voidUMLNotation:Theabstractclassnameandtheabstractmethodnamesareitalicized.Circle9.javaCylinder9.javapage254-25715说明•非抽象类(具体类)不能包含抽象方法。•如果抽象父类的子类,没有实现所有的抽象方法,它必须声明为抽象的(在这个类声明的前面加上abstract关键词)。•也就是说,在一个由抽象类扩展出来的非抽象类中,所有的抽象方法都必须实现,即使这个子类不使用它们。Page25716说明抽象类不能用new运算符实例化,但仍应定义它的构造方法,这种构造方法将在它子类的构造方法中被调用。例如,GeometricObject的构造方法在Circle类和Rectangle类中被调用。17说明(了解)允许声明没有抽象方法的抽象类。(用于定义新子类)子类可以被声明是抽象的,即使它的父类是具体的。子类可以覆盖它父类的方法,并将其声明为抽象的。(当父类方法中的实现在子类中无效时)18说明•不能用new运算符创建抽象类的实例,但是,抽象类可以用作数据类型。•下面的语句创建了一个元素是GeometricObject类型的数组:GeometricObject[]geo=newGeometricObject[10];19例9.1Δ使用GeometricObject类•目标:编写程序,创建两个几何对象,一个圆和一个矩形。调用equalArea方法检查两个对象是否有相同的面积,调用displayGeometricObject方法显示这些对象的信息。TestGeometricObject20输出结果:Thetwoobjectshavethesamearea?false[Circle]radius=5.0Theareais78.53981633974483Theperimeteris31.41592653589793[Rectangle]width=5.0andheight=3.0Theareais15.0Theperimeteris16.021接口接口(interface)是一种与类相似的结构,只包含常量和抽象方法。接口在许多方面与抽象类相近,但是抽象类出来包含常量和抽象方法之外,还可以包含变量和具体方法。为了区分接口和类,Java采用以下语法声明接口:publicinterfaceInterfaceName{constantdeclarations;/*常量声明*/methodsignatures;/*方法头标志*/}Page26022接口是一个特殊的类•在Java中,接口被看成是特殊的类。•和类一样,每个接口编译为独立的字节码文件。•接口的使用与抽象类很相似。例如:不能使用new操作符创建一个接口的实例;可以使用接口作为变量的数据类型等。23接口与抽象类•接口中的数据必须是常量;抽象类中的数据可以有常量,也可以有变量。•接口中的方法只有一个头标志,没有实现部分;抽象类中可以有抽象的方法,也可以有具体的方法。Page26224接口与抽象类在接口中,所有的数据域都是publicfinalstatic的,所有的方法都是publicabstract的.由于这个原因,这些修饰可以忽略,如下所示:等价于publicinterfaceT1{publicstaticfinalintK=1;publicabstractvoidp();}publicinterfaceT1{intK=1;voidp();}提示:接口中的常量能用下面的方式访问:接口名.常量名(例如,T1.K).25接口与抽象类•所有的类共享同一个根:Object类,但接口没有共同的根。•与类相似,接口也可以定义一个类型。•一个接口类型的变量可以引用任何实现该接口的类的实例。–如果一个类实现了一个接口,这个接口就类似于该类的一个父类。可以将一个接口当作一
本文标题:第9章 抽象类和接口
链接地址:https://www.777doc.com/doc-3375813 .html