您好,欢迎访问三七文档
运行环境:OfficeXP版本:ACCP4.0课程:Java作者:Lucky多态继承是指从一个基类(父类)派生出派生类(子类)的过程;继承使用关键字extends;对于类成员,可以使用public、protected、缺省和private这4种访问权限修饰符;对于类,可以使用public和缺省这2个访问权限;创建子类实例时,必须先执行父类的构造方法,然后再执行子类的构造方法;super关键字有两种主要用途,都与父类有关。回顾本章相关词汇(蓝色为关键字)单词说明abstract抽象,抽象的interface接口,界面implements实现final最终的,决定性的polymorphism多态,多态性casting转型overriddenmethod方法覆盖本章目标方法覆盖引用转型了解多态,在Java中实现多态抽象方法和抽象类,abstract关键字接口和实现接口,interface关键字和implements关键字final关键字类与类之间的关系(补充)父/子类中的同名成员上次课在讲述super关键字时,提到了父类和子类中存在同名成员的情况;如果是同名属性(即成员变量同名),那么可以通过this和super显式地区分开来;如果是同名方法(即成员方法同名),情况将会相对复杂。父/子类中成员方法仅仅同名classBaseClass//定义基类{publicvoidfun(){……//具体实现代码略}}classDerivedClassextendsBaseClass//派生类继承于基类{publicvoidfun(intx)//跟父类中有相同名称的方法{……//具体实现代码略}}/*如果仅仅只是名称相同,但参数列表不同的话,则构成方法重载*/父/子类中成员方法同原型classSuperClass//定义父类{publicvoidfun(){……//具体实现代码略}}classSubClassextendsSuperClass//子类继承于父类{publicvoidfun()//与父类中的方法完全同原型{……//具体实现代码略}}/*如果不但名称相同,而且连方法原型也完全相同的话,则构成方法覆盖*/方法覆盖在类的继承体系结构中,如果子类中出现了与父类中有同原型的方法,那么认为子类中的方法覆盖了父类中的方法(也称为方法重写);通过子类的实例调用被覆盖的方法时,将总是调用子类中的方法,而父类中的方法将被隐藏。方法覆盖示例classParentClass{//定义父类publicvoidfun(){System.out.println(这是父类中的方法。);}}classChildClassextendsParentClass{//子类继承于父类publicvoidfun(){//子类覆盖父类中的方法System.out.println(这是子类中的方法。);}}classOverriddenTest{//用于容纳main方法publicstaticvoidmain(String[]args){ParentClassparObj=newParentClass();parObj.fun();//父类的实例调用此方法ChildClasschiObj=newChildClass();chiObj.fun();//子类的实例调用此方法}}区分方法覆盖和方法重载方法覆盖(重写)和方法重载是两个极易混淆的概念,必须严格区分;方法覆盖出现的前提条件之一是必须有继承发生的情况下,而且要求父类和子类中的方法必须同原型;方法重载时,继承并不是必需的,它只要求方法名称相同,而参数列表则必须不同,换言之,各方法的原型其实是不同的。引用转型基类的引用可以指向派生类的对象,如:BaseClassobj=newDerivedClass();这样的语句是合法的;但是派生类的引用则不可以指向基类的对象,如:DerivedClassobj=newBaseClass();这样的语句将引发错误。引用转型示例classPerson{//定义人类……}classStudentextendsPerson{//学生类继承于人类……}publicclassOverriddenDemo{publicstaticvoidmain(String[]args){//正确,所有的学生一定是人Personper=newStudent();//错误,并不是所有的人都是学生Studentstd=newPerson();}}问题既然基类的引用可以指向派生类的实例,如果基类和派生类中存在方法覆盖的情况,那么通过基类的引用将会调用到哪个类中的方法呢?示例classShapes{//基本形状类publicvoiddraw(){//绘图的方法System.out.println(绘制了一个基本形状。);}}classCircleextendsShapes{//圆形类继承于基本形状类publicvoiddraw(){//覆盖父类的绘图方法System.out.println(绘制了一个圆形。);}}classSquareextendsShapes{//正方形类继承与基本形状类publicvoiddraw(){//覆盖父类的绘图方法System.out.println(绘制了一个正方形。);}}publicclasspolymorphismDemo{publicstaticvoidmain(String[]args){Shapesobj=newShapes();//父类的引用指向父类的实例obj.draw();//调用绘图方法obj=newCircle();//父类的引用指向子类的实例obj.draw();//调用绘图方法obj=newSquare();//父类的引用指向子类的实例obj.draw();//调用绘图方法}}多态从上例中可以看出,父类的引用指向哪个类的实例就调用哪个类中的方法;同样是使用父类的引用,调用同一个名称的方法,却可以得到不同的调用结果,这就是Java中的多态,即:同一函数,多种形态;实际上多态包括动态多态和静态多态。静态多态静态多态也称为编译时多态,即在编译时决定调用哪个方法;静态多态一般是指方法重载;只要构成了方法重载,就可以认为形成了静态多态的条件;静态多态与是否发生继承没有必然联系。动态多态动态多态也称为运行时多态,即在运行时才能确定调用哪个方法;形成动态多态必须具体以下条件:必须要有继承的情况存在;在继承中必须要有方法覆盖;必须由基类的引用指向派生类的实例,并且通过基类的引用调用被覆盖的方法;由上述条件可以看出,继承是实现动态多态的首要前提。抽象方法在某些情况下,基类无法(或者没有必要)提供被覆盖方法的具体实现,那么就可以将此方法声明成抽象方法;使用关键字abstract声明抽象方法,一般语法:[访问权限]abstract返回值类型方法名称(参数列表);如:publicabstractvoiddraw();抽象类如果某个类中包含有抽象方法,那么该类就必须定义成抽象类;定义抽象类同样使用关键字abstract,一般语法:[访问权限]abstractclass类名{成员列表}如:publicabstractclassShapes{publicabstractvoiddraw();}抽象类的注意事项抽象类不可以直接实例化,只可以用来继承;抽象类的派生子类应该提供对其所有抽象方法的具体实现;可以这么认为,抽象方法实际上就是由抽象基类强制要求其派生子类必须实现的方法原型;如果抽象类的派生子类没有实现其中的所有抽象方法,那么该派生子类仍然是抽象类,只能用于继承,而不能实例化;抽象类中也可以包含有非抽象的方法;构造方法和静态方法不可以修饰为abstract。修改前面的案例abstractclassShapes{//基本形状类,抽象类publicabstractvoiddraw();//绘图方法,抽象方法}classCircleextendsShapes{//圆形类继承于基本形状类publicvoiddraw(){//实现抽象父类的抽象绘图方法System.out.println(绘制了一个圆形。);}}classSquareextendsShapes{//正方形类继承与基本形状类publicvoiddraw(){//实现抽象父类的抽象绘图方法System.out.println(绘制了一个正方形。);}}publicclassabstractDemo{//该类用于容纳main方法publicstaticvoidmain(String[]args){Shapesobj;obj=newCircle();//父类的引用指向子类的实例obj.draw();//调用绘图方法obj=newSquare();//父类的引用指向子类的实例obj.draw();//调用绘图方法}}接口如果某个类中的所有方法都是抽象方法,那么可以考虑将该类定义为接口;定义接口使用关键字interface,一般语法:[访问权限]interface接口名{成员列表}如:publicinterfaceIMyInterface{……}实现接口与抽象类相似,接口同样不可以实例化,只能用于实现;如果某类要实现接口,则使用implements关键字,一般语法:[访问权限]class类名implements接口名{成员列表}如:publicclassMyClassimplementsIMyInterface{……}接口示例源文件IMyInterface.javapackageaaa;//定义接口publicinterfaceIMyInterface{/*接口中的所有方法都默认为抽象方法无需加abstract关键字*/publicintadd(intx,inty);publicintsub(intx,inty);}packagebbb;importaaa.IMyInterface;//MyClass类实现于IMyInterface接口publicclassMyClassimplementsIMyInterface{//实现接口中的抽象方法publicintadd(intx,inty){return(x+y);}publicintsub(intx,inty){return(x-y);}}源文件MyClass.java接口的注意事项接口中不能定义非抽象方法,也就是说接口中不能包含有函数实体;接口中的所有方法都默认为抽象方法,无需在每个方法前加abstract关键字;接口的实现类应该提供对接口中所有抽象方法的具体实现,否则将成为抽象类;与抽象类和它的继承类相似,也可以使用接口的引用指向其实现类的对象,从而达到动态多态的效果。接口示例(续)/*InterfaceDemo.java源文件*///导入必要的接口和类importaaa.IMyInterface;importbbb.MyClass;//用于容纳main方法publicclassInterfaceDemo{publicstaticvoidmain(String[]args){//使用接口的引用指向实现类的实例IMyInterfaceobj=newMyClass();System.out.println(两数的和是:+obj.add(20,30));System.out.println(两数的差是:+obj.sub(30,20));}}关于接口的更多知识Java只支持单继承,而不能象C++那样可以多重继承,接口正是为了弥补这一点;某个类只能继承于一个父类,但可以实现多个接口,如:publicclass实现类名implements接口1,接口2,……,接口n{成员列表}关于接口的更多知识(续)Java中还允许一个接口继承于另一个接口,即由父接口派生出子接口,如:publicinterface子接口名extends父接口名{成员列表}这样的话,甚至可以使用父接口的引用
本文标题:多态
链接地址:https://www.777doc.com/doc-3650079 .html