您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > Java面向对象编程(3-3)
1第三章面向对象编程3软件工程学院主讲人:张昊23.8多态什么是多态JAVA里没有多继承,一个类只能有一个父类。一个父类可以有多个子类,而在子类里可以重写父类的方法,每个子类里重写的代码不一样。这样用父类的变量去引用子类的实例,在调用相同的方法时得到的结果不一样,这就是多态,也就是调用相同的方法会有不同的结果。3Java语言允许用父类的变量去引用子类的实例。Animalxiaohuang=newDog();//父类变量animal引用一个Animal子类Dog的实例我们称Animal是xiaohuang的声明(形式)类型Dog是xiaohuang的实际类型。Animalxiaohua=newCat();//父类变量xiaohua引用另一个Animal子类Cat的实例用父类的变量去引用子类的实例4例1:publicclassFather{//父类publicvoidhitChild(){//父类有一个打孩子方法}}publicclassSon1extendsFather{//子类1//重写父类打孩子方法publicvoidhitChild(){System.out.println(为什么打我?我做错什么了!);}}publicclassSon2extendsFather{//子类2//重写父类打孩子方法publicvoidhitChild(){System.out.println(我知道错了,别打了!);}}publicclassSon3extendsFather{//子类3//重写父类打孩子方法publicvoidhitChild(){System.out.println(我跑,你打不着!);}}5例1://测试类publicclassTest{publicstaticvoidmain(Stringargs[]){Fatherfather;father=newSon1();father.hitChild();father=newSon2();father.hitChild();father=newSon3();father.hitChild();}}都调用了相同的方法,出现了不同的结果!这就是多态的表现!6【3.12】ClassSuperClass{voidmethod1(){System.out.println(“method1inSuperClass”);}voidmethod2(){System.out.println(“method2inSuperClass”);}}classSubClassextendsSuperClass{voidmethod1(){System.out.println(“method1inSubClass”);}voidmethod3(){System.out.println(“method3inSubClass”);}}7classMain{publicstaticvoidmain(Stringargs[]){SuperClassa=newSubClass();//声明类型为SuperClass,实际类型是SubClassa.method1();//method1inSubClass,SubClass对SuperClass中的method1进行了重写a.method2();//method2inSuperClass,SubClass中没有method2,只能调用SuperClass的method2//a.method3();错误}}8如果我们调用a的method3()方法,则无法通过编译。这是因为java语言为强制类型的语言,编译时会检查形式类型是否提供该方法。a的形式类型是SuperClass,不提供method3()方法,虽然a的实际类型有method3()方法,但编译时只检查形式类型,不检查实际类型。所以形式类型也称为编译期类型,实际类型也称为执行期类型。注意:9注意:通常我们不会去写“SuperClassa=newSubClass();”但实际应用中,形式类型和实际类型不同的情况却往往在不知不觉中发生。看下例:10【例3.13】classOther{staticvoidmethod4(SuperClassa){//a的形式类型是SuperClass,实际类型则不一定是SuperClassa.method1();}}publicclassMain{publicstaticvoidmain(String[]args){SubClassb=newSubClass();Other.method4(b);//相当于SuperClassa=newSubClass();}/*调用类方法method4(),需要一个SuperClass类型的参数,而传入的参数b的实际类型是SubClass,这就造成了形式类型和实际类型的不一致*/}11在java语言中,多态性体现在两个方面:1.由方法重载实现的静态多态性(编译时多态)在编译阶段,要调用哪个被重载的方法,编译器会根据参数的不同调用相应的方法。重载是一个类中多态性的一种表现。2.方法重写实现的动态多态性(运行时多态)在JAVA中可以用父类的变量去引用子类的实例,这样在调用相同的方法时会得到不同的结果。重写是父类与子类之间多态性的一种表现,注意:12重写时必须遵循两个原则:重写时必须遵循两个原则:重写后的方法不能比被重写的方法有更严格的访问权限;重写后的方法不能比被重写的方法有更多的异常。13从上面的例子可以加以归纳p46,多态的(方法重写实现的动态多态)发生必须是:(1)有直接或间接继承关系的两个类,子类重写父类的方法。(2)实际类型为子类的对象,被当成父类来使用,调用重写方法。注意:14java运行时系统根据调用该方法的实例,来决定调用哪个方法。1.对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;2.如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。重写方法的调用原则153.8.2多态带来的优越性多态是建立在继承的基础上的,没有继承,就不会有多态。继承的目的:一是为了继承程序代码,达到程序代码的复用;二是为了继承接口,达到接口的复用。163.8.3多态的机制只能用在实例方法上多态机制只能用在实例方法上:1.不能用在成员变量上。对于成员变量,形式类型决定一切,完全和实际类型无关2.不能用在类方法上17【例3.14】多态的机制不能用在成员变量上classSuperClass{intfield1=‘a’;intfield2=‘b’;}classSubClassextendsSuperClass{intfield1=‘c’;intfield3=‘d’;}publicclassMain{publicstaticvoidmain(Stringargs[]){SuperClassa=newSubClass();System.out.println(a.field1);//a,而不是cSystem.out.println(a.field2);//b//System.out.println(a.field3);错误}}18【例3.15】多态的机制不能用在类方法上classSuperClass{staticvoidmethod1(){System.out.println(“method1inSuperClass”);}staticvoidmethod2(){System.out.println(“method2inSuperClass”);}}classSubClassextendsSuperClass{staticvoidmethod1(){System.out.println(“method1inSubClass”);}staticvoidmethod3{System.out.println(“method3inSubClass”);}19publicclassMain{publicstaticvoidmain(Stringargs[]){SuperClassa=newSubClass();a.method1();//结果为method1inSuperClassa.method2();//结果为method2inSuperClass//a.method3();错误}}【例3.15】203.9final和abstract关键字3.9.1finalfinal可以修饰类、变量和方法。1.final修饰变量用final关键字修饰的标识符被称为常量。例finalinta=5;//a为常量注意:修饰成员变量时,定义的同时必须给出初始值,而修饰局部变量时不做要求。21final修饰的标识符被称为常量classaa{intb=0;finalinta=5;//a是常量,定义的同时必须给出初始值voidf(){b=4;a=4;//出错!!!}}222.用final关键字修饰的类不能被继承finalclassA{……}//A为最终类,不可以被继承。classBextendsA{……}//出错!!用final关键字修饰类233.用final关键字修饰的方法不能被重写例如:finalintf(){……}classA{finalvoidf(){}}classBextendsA{voidf(){}//出错,用final关键字修饰的方法不能被重写}注意:如果一个类为final类,那么它的所有方法都为隐式的final方法。用final关键字修饰方法243.9.2abstractabstract可修饰符类和方法1.用abstract关键字修饰的类叫做抽象类2.用abstract关键字修饰的方法叫做抽象方法格式如下:abstractclassabstractClass{…}//抽象类abstractreturnTypeabstractMethod(paramlist)//抽象方法25抽象方法抽象方法:用abstract修饰,只有方法的声明,没有方法体如:abstractvoidf();注意:•抽象方法必须在子类中给出具体实现•若类中包含了抽象方法,则该类必须被定义为抽象类•抽象方法不能是私有的(private)不能是静态的(static)26抽象类:用abstract修饰的类。如:abstractclass类名//定义抽象类{typevar1;//声明数据成员;voidf(inta,intb)//声明方法;{…………}abstract返回数据类型方法名(参数…);//声明抽象方法;}抽象类271.不能使用抽象类来创建对象(抽象类不能实例化)2.如果一个类中有抽象方法,这个类一定是抽象类3.如果一个类被声明为抽象类,类体中也可以没有抽象方法4.如果一个类继承了抽象类,在这个类中必须实现它所继承的抽象类的所有抽象方法(抽象方法必须被重写)一抽象父类A定义了两个抽象方法f1,f2;B、C、D类都继承于A,那么B、C、D都要实现方法f1和f2。抽象类28抽象类是一种比普通类更高层次的抽象,类似于类的框架抽象类的作用是为了被继承。通过抽象类创建的子类具有一定的共性,如都要实现父类中的抽象方法抽象类的作用29[例3.16]abstractclassA{//定义抽象类Ainti;abstractvoidabstractFunc();//声明抽象方法voidnotabstractFunc(){//一般方法i=0;System.out.println(“fromA:”+i);}}classBextendsA{//B继承了抽象类AvoidabstractFunc(){//必须实现A类中的抽象方法i=1;System.out.println(“fromB:”+i);}}30classCextendsB{//C继承了类BvoidabstractFunc(){//重写了父类B中的方法,而不是A类中抽象方法的实现i=3;System.out.println(“fromC:”+i);}}classDextendsC{publ
本文标题:Java面向对象编程(3-3)
链接地址:https://www.777doc.com/doc-6288817 .html