《第6章继承和多态课件.ppt》由会员分享,可在线阅读,更多相关《第6章继承和多态课件.ppt(36页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第6章继承和多态第1页,此课件共36页哦学习目标学习目标继承可以有效地组织程序结构,明确类之间的继承可以有效地组织程序结构,明确类之间的关系,充分利用已有的类来创建新类,以完成关系,充分利用已有的类来创建新类,以完成更复杂的设计开发。多态则可以统一多个相关更复杂的设计开发。多态则可以统一多个相关类对外的接口,并在运行时根据不同的情况执类对外的接口,并在运行时根据不同的情况执行不同的操作,提高类的抽象度和灵活性。本行不同的操作,提高类的抽象度和灵活性。本章的学习目标就是掌握继承和多态。章的学习目标就是掌握继承和多态。第2页,此课件共36页哦本章重点本章重点继承继承多态多态抽象类抽象类接口接口包包
2、第3页,此课件共36页哦当一个类拥有另一个类的数据和操作时,就当一个类拥有另一个类的数据和操作时,就称这两个类之间具有继承关系,被继承的类称这两个类之间具有继承关系,被继承的类称为称为父类父类或或超类超类,继承的类称为,继承的类称为子类子类。一个父类可以同时拥有多个子类,该父类实一个父类可以同时拥有多个子类,该父类实际上是所有子类的公共成员变量和公共方法际上是所有子类的公共成员变量和公共方法的集合,而子类是父类的特殊化,可对公共的集合,而子类是父类的特殊化,可对公共成员变量和方法在功能、内涵方面加以扩展成员变量和方法在功能、内涵方面加以扩展和延伸。和延伸。第4页,此课件共36页哦面向对象的继承
3、特性中,还有一个关于单继面向对象的继承特性中,还有一个关于单继承和多继承的概念。承和多继承的概念。单继承是指任何类都只有一个父类。单继承是指任何类都只有一个父类。多继承是指一个类可以有一个以上的父类,它多继承是指一个类可以有一个以上的父类,它静态数据和操作从所有这些父类中继承的。静态数据和操作从所有这些父类中继承的。Java只支持单重继承,但支持界面,一个只支持单重继承,但支持界面,一个类可以实现多个界面。利用界面可以得到多类可以实现多个界面。利用界面可以得到多继承的优点,又没有多继承混乱、复杂的问继承的优点,又没有多继承混乱、复杂的问题。题。第5页,此课件共36页哦Java继承:创建子类继承
4、:创建子类Java中的继承是通过中的继承是通过extends关键字来实现的。格式关键字来实现的。格式为为:class子类名子类名extends父类名称父类名称在定义类时用在定义类时用extends关键字指明新定义类的父类,就关键字指明新定义类的父类,就在两个类之间建立了继承关系,新定义的类被称为子类。在两个类之间建立了继承关系,新定义的类被称为子类。如果子类和父类如果子类和父类在同一个包中在同一个包中,它可以从父类那里继承所有,它可以从父类那里继承所有非非private的成员变量和方法作为自己的成员。的成员变量和方法作为自己的成员。如果子类和父类如果子类和父类不在同一个包中不在同一个包中,它可
5、以从父类那里继承,它可以从父类那里继承protected、public的的成员变量和方法作为自己的成员的的成员变量和方法作为自己的成员.第6页,此课件共36页哦【例例】应用继承性的实例。应用继承性的实例。classStudent/自定义自定义“学生学生”类类intstu_id;/定义属性:学生学号定义属性:学生学号voidset_id(intid)/定义方法:设置学号定义方法:设置学号stu_id=id;voidshow_id()/定义方法:显示学号定义方法:显示学号System.out.println(thestudentIDis:+stu_id);classUniversityStuden
6、textendsStudent/定义子类定义子类intdep_number;/定义子类特有的属性变量定义子类特有的属性变量voidset_dep(intdep_num)/定义子类特有的方法定义子类特有的方法dep_number=dep_num;voidshow_dep()System.out.println(thedep_numberis:+dep_number);publicstaticvoidmain(Stringargs)UniversityStudentLee=newUniversityStudent();Lee.set_id(2007070130);/继承父类学生的属性继承父类学生的
7、属性Lee.set_dep(701);/使用本类的属性使用本类的属性Lee.show_id();/继承父类学生的方法继承父类学生的方法Lee.show_dep();/使用本类的方法使用本类的方法第7页,此课件共36页哦成员变量的隐藏和方法的覆盖成员变量的隐藏和方法的覆盖1.成员变量的继承成员变量的继承子类可以继承父类的所有非私有成员变量。子类可以继承父类的所有非私有成员变量。2.成员变量的继承成员变量的继承子类重新定义一个从父类那里继承来的成员变量变量完全相同的子类重新定义一个从父类那里继承来的成员变量变量完全相同的变量,称为成员变量的隐藏。变量,称为成员变量的隐藏。3.方法的覆盖方法的覆盖方
8、法的覆盖是指子类重定义从父类继承来的一个同名方法,方法的覆盖是指子类重定义从父类继承来的一个同名方法,此时子类将清除父类方法的影响。此时子类将清除父类方法的影响。注意注意:子类在重新定义父类已有的方法时,应保持与父类完子类在重新定义父类已有的方法时,应保持与父类完全相同的方法头声明,即应与父类有完全相同的方法名、相全相同的方法头声明,即应与父类有完全相同的方法名、相同的参数表和相同的返回类型。同的参数表和相同的返回类型。第8页,此课件共36页哦【例例】成员变量的隐藏和方法的覆盖示例。成员变量的隐藏和方法的覆盖示例。classSuperClassintx;voidsetX()x=0;classS
9、ubClassextendsSuperClassintx;/成员变量的隐藏成员变量的隐藏voidsetX()/方法的覆盖方法的覆盖x=5;第9页,此课件共36页哦方法的覆盖与成员变量的隐藏的区别为:方法的覆盖与成员变量的隐藏的区别为:子类隐藏父类的成员变量只是使之不可见,父类子类隐藏父类的成员变量只是使之不可见,父类的同名成员变量在子类对象中仍然占有自己独立的同名成员变量在子类对象中仍然占有自己独立的内存空间;的内存空间;而子类方法对父类同名方法的覆盖将清除父类方而子类方法对父类同名方法的覆盖将清除父类方法占用的内存,从而使父类方法在子类对象中不法占用的内存,从而使父类方法在子类对象中不存在。
10、存在。方法的覆盖与成员变量的隐藏的意义:将父类方法的覆盖与成员变量的隐藏的意义:将父类行为和状态改为自身的行为和状态,对外仍保行为和状态改为自身的行为和状态,对外仍保持统一的接口和名字,不失继承性。持统一的接口和名字,不失继承性。第10页,此课件共36页哦super子类对父类的同名成员变量和方法,分别实子类对父类的同名成员变量和方法,分别实行隐藏和覆盖。但是,有时需要在子类中访行隐藏和覆盖。但是,有时需要在子类中访问父类的变量、父类的方法,问父类的变量、父类的方法,Java提供的提供的super就可以实现这访问。它的使用有三种就可以实现这访问。它的使用有三种情况:情况:访问被隐藏的父类成员变量
11、,如:访问被隐藏的父类成员变量,如:super.VariableName调用父类中被覆盖的方法,如:调用父类中被覆盖的方法,如:super.MethodName调用父类中的构造方法,如:调用父类中的构造方法,如:super(paramList)第11页,此课件共36页哦多态性多态性多态性是面向对象程序设计的又一特征。多态性是面向对象程序设计的又一特征。面向过程的语言编程的主要工作是编写一系列过面向过程的语言编程的主要工作是编写一系列过程或函数,这些过程和函数各自对应一定的功能,程或函数,这些过程和函数各自对应一定的功能,它们之间不能重名,否则在调用时,就会产生歧它们之间不能重名,否则在调用时,
12、就会产生歧异和错误。异和错误。而在面向对象的程序设计中,有时却需要利用这而在面向对象的程序设计中,有时却需要利用这样的样的“重名重名”现象来提高程序的抽象度和简洁性。现象来提高程序的抽象度和简洁性。第12页,此课件共36页哦多态性是指同名的不同方法在程序中共存。多态性是指同名的不同方法在程序中共存。即为同一个方法定义几个版本,运行时根据不即为同一个方法定义几个版本,运行时根据不同情况执行不同的版本。调用者只需使用同一同情况执行不同的版本。调用者只需使用同一个方法名,系统会根据不同情况,调用相应的个方法名,系统会根据不同情况,调用相应的不同方法,从而实现不同的功能。不同方法,从而实现不同的功能。
13、在在Java语言中,多态性的实现有两种方式:语言中,多态性的实现有两种方式:1、覆盖实现多态性、覆盖实现多态性2、重载实现多态性、重载实现多态性第13页,此课件共36页哦1、覆盖实现多态性、覆盖实现多态性覆盖实现多态性覆盖实现多态性通过子类对继承父类方法的重定义来实现。使通过子类对继承父类方法的重定义来实现。使用时注意:在子类重定义父类方法时,要求与用时注意:在子类重定义父类方法时,要求与父类原型(参数个数、类型、顺序)完全相同。父类原型(参数个数、类型、顺序)完全相同。第14页,此课件共36页哦重写方法的调用规则重写方法的调用规则对于重写的方法,对于重写的方法,Java运行时系统根据调用该运
14、行时系统根据调用该方法的实例的类型来决定选择哪个方法调用。方法的实例的类型来决定选择哪个方法调用。对于类的一个实例,如果子类重写了父类的方对于类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法。如果子类法,则运行时系统调用子类的方法。如果子类继承了父类的方法继承了父类的方法(未重未重),则运行时系统调用,则运行时系统调用父类的方法。因此,一个对象可以通过引用子父类的方法。因此,一个对象可以通过引用子类的实例来调用于类的方法。类的实例来调用于类的方法。第15页,此课件共36页哦【例例6-5】重写方法的调用规则示例。】重写方法的调用规则示例。classAvoidcallme()Sy
15、stem.out.println(InsideAscallme()method);classBextendsAvoidcallme()System.out.println(InsideBscallme()method);publicclassDispatchpublicstaticvoidmain(Stringargs)Aa=newB();a.callme();运行结果为:运行结果为:InsideBscallme()method第16页,此课件共36页哦方法重写的两个原则:方法重写的两个原则:改改写写后后的的方方法法不不能能比比被被重重写写的的方方法法有有更更严严格格的的访问权限。访问权限。改
16、改写写后后的的方方法法不不能能比比被被重重写写的的方方法法产产生生更更多多的的例外。例外。第17页,此课件共36页哦2、重载实现多态性、重载实现多态性重载实现多态性是通过定义类中的多个同名的不同方重载实现多态性是通过定义类中的多个同名的不同方法来实现的。编译时则根据参数(个数、类型、顺序)法来实现的。编译时则根据参数(个数、类型、顺序)的不同来区分不同的方法。通过重载可定义多种同类的不同来区分不同的方法。通过重载可定义多种同类的操作方法,调用时根据不同需要选择不同的操作。的操作方法,调用时根据不同需要选择不同的操作。与方法的覆盖不同,重载不是子类对父类同名方法的重新与方法的覆盖不同,重载不是子
17、类对父类同名方法的重新定义,而是类对自身已有的同名方法的重新定义。定义,而是类对自身已有的同名方法的重新定义。由于重载发生在一个类里,不能用类名来区分不同的方法,由于重载发生在一个类里,不能用类名来区分不同的方法,所以采用不同的形式参数列表,包括形式参数的个数、类型、所以采用不同的形式参数列表,包括形式参数的个数、类型、顺序的不同,来区分重载的方法。顺序的不同,来区分重载的方法。第18页,此课件共36页哦【例例】重重载载实实现现多多态态性性举举例例。该该类类中中定定义义了了矩矩形形,用用四四个个实实例例变变量量来来定定义义这这个个矩矩形形的的左左上上角角和和右右下下角角的的坐坐标标,x1、y1
18、、x2、y2。另另外外定定义义了了三三个个同同名名的的不不同同buildRect()方法为这些实例变量设置值。方法为这些实例变量设置值。importjava.awt.Point;classMyRectintx1=0;inty1=0;intx2=0;inty2=0;MyRectbuildRect(intx1,inty1,intx2,inty2)this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;returnthis;MyRectbuildRect(PointtopLeft,PointbottomRight)x1=topLeft.x;y1=topLeft.y;x
19、2=bottomRight.x;y2=bottomRight.y;returnthis;MyRectbuildRect(PointtopLeft,intw,inth)x1=topLeft.x;y1=topLeft.y;x2=(x1+w);y2=(y1+h);returnthis;第19页,此课件共36页哦voidprintRect()System.out.println(MyRect:);publicstaticvoidmain(Stringargs)MyRectrect=newMyRect();rect.buildRect(25,25,50,50);rect.printRect();Syst
20、em.out.println(*);rect.buildRect(newPoint(10,10),newPoint(20,20);rect.printRect();System.out.println(*);rect.buildRect(newPoint(10,10),50,50);rect.printRect();System.out.println(*);第20页,此课件共36页哦抽象类抽象类抽象类:用抽象类:用abstract关键字来修饰的类。关键字来修饰的类。声明为声明为abstract的类不能被实例化。它只提供的类不能被实例化。它只提供了一个基础,为了实例化,该类必须作为父类,了一个
21、基础,为了实例化,该类必须作为父类,子类可以通过继承它,然后添加自己的属性和子类可以通过继承它,然后添加自己的属性和方法形成具体的有意义的类。方法形成具体的有意义的类。抽象类必须被继承。抽象类必须被继承。第21页,此课件共36页哦抽象方法:用抽象方法:用abstract来修饰一个方法时,来修饰一个方法时,该方法叫做抽象方法。该方法叫做抽象方法。抽象方法必须被重写抽象方法必须被重写抽象方法只有声明,不能有实现抽象方法只有声明,不能有实现定义了抽象方法的类必须是抽象类定义了抽象方法的类必须是抽象类第22页,此课件共36页哦【例例】抽象类举例。抽象类举例。abstractclassAabstract
22、voidcallme();voidmetoo()System.out.println(InsideAsmetoo()method);classBextendsAvoidcallme()System.out.println(InsideBscallme()method);publicclassAbstractpublicstaticvoidmain(Stringargs)Ac=newB();c.callme();c.metoo();第23页,此课件共36页哦接口接口接口(接口(interface)就是方法定义和常量值)就是方法定义和常量值的集合。从本质上讲,接口是一种特殊的抽的集合。从本质上讲,
23、接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定象类,这种抽象类中只包含常量和方法的定义,而没有方法的实现。义,而没有方法的实现。通过接口可以实现不相关类的相同行为,而不通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。需要考虑这些类之间的层次关系。通过接口可以指明多个类需要实现的方法。通过接口可以指明多个类需要实现的方法。通过接口可以了解对象的交互界面,而不需了通过接口可以了解对象的交互界面,而不需了解对象所对应的类。解对象所对应的类。第24页,此课件共36页哦接口是用来实现类间多重继承功能的结构接口是用来实现类间多重继承功能的结构.在在Java中,出于简化程序结
24、构的考虑,不支持类间的多重中,出于简化程序结构的考虑,不支持类间的多重继承而只支持单重继承,即一个类至多只能有一个直接父类。继承而只支持单重继承,即一个类至多只能有一个直接父类。接口的实现功能比多重继承更强接口的实现功能比多重继承更强接口把方法的定义和类的层次区分开来,通过它可以在运行接口把方法的定义和类的层次区分开来,通过它可以在运行时动态地定位所调用的方法;时动态地定位所调用的方法;同时,也可以实现同时,也可以实现“多重继承多重继承”,且一个类可以实现多个接口。,且一个类可以实现多个接口。正是这些机制使得接口提供了比多重继承更简单,更灵活,而且正是这些机制使得接口提供了比多重继承更简单,更
25、灵活,而且更强健的功能。更强健的功能。第25页,此课件共36页哦1.接口的定义接口的定义publicinterface接口名接口名extends接口列表接口列表/常量定义和方法定义常量定义和方法定义public指明任意类均可以使用这个接口。在缺省情况指明任意类均可以使用这个接口。在缺省情况下,只有与该接口定义在同一个包中的类才可以访问下,只有与该接口定义在同一个包中的类才可以访问这个接口。这个接口。extends子句与类声明中的子句与类声明中的extends子句基本相同,不子句基本相同,不同的是一个接口可以有多个父接口,用逗号隔开,而同的是一个接口可以有多个父接口,用逗号隔开,而一个类只能有一
26、个父类。子接口继承父接口中所有常一个类只能有一个父类。子接口继承父接口中所有常量和方法。量和方法。第26页,此课件共36页哦接口体中包括常量定义和方法定义,其格式如下所接口体中包括常量定义和方法定义,其格式如下所示:示:typeconstantName=Value;returnTypemethodName(paramList);在接口中定义的常量可以被用来实现该接口的多个类共享,在接口中定义的常量可以被用来实现该接口的多个类共享,与与C语言中的语言中的const定义常量是相似的。定义常量是相似的。在接口中定义的常量具有在接口中定义的常量具有public、final、static的属性。的属性。
27、接口中只进行方法的声明,而不提供方法的实现,接口中只进行方法的声明,而不提供方法的实现,所以,方法定义没有方法体,且用分号所以,方法定义没有方法体,且用分号(;)结尾。在结尾。在接口中声明的方法具有接口中声明的方法具有public和和abstract属性。属性。另外,如果在子接口中定义了和父接口同名的常量或相另外,如果在子接口中定义了和父接口同名的常量或相同的方法,则父接口中的常量被隐藏,方法被覆盖。同的方法,则父接口中的常量被隐藏,方法被覆盖。第27页,此课件共36页哦例:例:interfaceCollectionintMAX_NUM=100;voidadd(ObjectobjAdd);vo
28、iddelete(ObjectobjDelet);Objectfind(ObjectobjFind);intcurrentCount();接口定义中声明了一个常量和四个方法。这个接口可以由接口定义中声明了一个常量和四个方法。这个接口可以由队列、堆栈、链表等来实现。队列、堆栈、链表等来实现。第28页,此课件共36页哦2.接口的实现接口的实现接口的声明仅仅给出了抽象方法,要具体地接口的声明仅仅给出了抽象方法,要具体地实现接口所规定的功能,则需某个类为接口实现接口所规定的功能,则需某个类为接口中的抽象方法定义实在的方法体,这就称为中的抽象方法定义实在的方法体,这就称为接口的实现接口的实现。在类的声明
29、中,用在类的声明中,用implements句子表示一句子表示一个类将要实现某个接口,在类体中可以引用个类将要实现某个接口,在类体中可以引用接口中定义的常量,而且必须实现接口中定接口中定义的常量,而且必须实现接口中定义的所有方法。一个类可以实现多个接口,义的所有方法。一个类可以实现多个接口,在在implements子句中用逗号分隔。子句中用逗号分隔。第29页,此课件共36页哦【例例】接口的实现:在类接口的实现:在类FIFOQueue中实现上面所定义的接口中实现上面所定义的接口collection。classFIFOQueueimplementscollectionvoidadd(Objectob
30、j).voiddelete(Objectobj).Objectfind(Objectobj).intcurrentCount.第30页,此课件共36页哦注意:注意:在类中实现接口所定义的方法时,方法的声明在类中实现接口所定义的方法时,方法的声明必须与接口中所定义的完全一致。必须与接口中所定义的完全一致。在类中实现接口所定义的方法时,必须显式地在类中实现接口所定义的方法时,必须显式地使用使用publicpublic修饰符,否则将被系统警告为缩小修饰符,否则将被系统警告为缩小了接口中定义的方法的访问控制范围。了接口中定义的方法的访问控制范围。抽象类可以不实现接口的抽象方法,而非抽象抽象类可以不实现
31、接口的抽象方法,而非抽象类必须实现接口中的所有方法。类必须实现接口中的所有方法。第31页,此课件共36页哦包包利用利用Java语言开发实际系统时,可以利用语言开发实际系统时,可以利用“包包”来管来管理类。包是类和接口的集合,为了方便编程和管理,理类。包是类和接口的集合,为了方便编程和管理,通常把需要在一起工作的类放在一个包里。通常把需要在一起工作的类放在一个包里。为为Java创建一个源码文件的时候,它通常叫做一个创建一个源码文件的时候,它通常叫做一个“编辑单元编辑单元”,每个编辑单元必须有一个以,每个编辑单元必须有一个以java结尾的结尾的名字。名字。缺省情况下,系统为每个缺省情况下,系统为每
32、个.java源文件创建一个无名包,源文件创建一个无名包,该文件中定义的所有类都隶属于该包,但由于该包无该文件中定义的所有类都隶属于该包,但由于该包无名字,所以不能被其它包引用。为了解决这个问题,名字,所以不能被其它包引用。为了解决这个问题,就要创建有名包。就要创建有名包。第32页,此课件共36页哦标准的标准的Java包列表包列表包功能描述java.applet包含一些用于创建Java小应用程序的类java.awt包含一些编写平台无关的图形用户界面(GUI)应用程序的类。它包含几个子包,包括java.awt.peer和java.awt.imagejava.io包含一些用作输入输出(I/O)处理的
33、类。数据流就包含在这里java.1ang包含一些基本Java类。java.1ang是被隐式地引入的,所以用户不必引入它的类包含用于建立网络连接的类。与java.io同时使用以完成与网络有关的读和写java.util包含一些其他的工具和数据结构,如编码、解码、向量和堆栈等第33页,此课件共36页哦包的创建包的创建用用package关键字创建包,而且该语句是关键字创建包,而且该语句是.java源文件的源文件的第一个语句,前面不能有注释和空格。格式为第一个语句,前面不能有注释和空格。格式为:package包名;包名;例如:例如:packageSubClass;packageMyClass.SubCl
34、ass;实际上,创建包就是在当前目录下创建一个子目录实际上,创建包就是在当前目录下创建一个子目录SubClass,以便存放这个包中包含的所有类的,以便存放这个包中包含的所有类的.class文件。文件。上面的第二个语句中的上面的第二个语句中的“.”代表了目录分隔符。即包中的代表了目录分隔符。即包中的类放在当前目录下的类放在当前目录下的SubClass子目录下的子目录下的MyClass子目录子目录下。下。第34页,此课件共36页哦package myclass.graphics;这条语句指定这个包中的这条语句指定这个包中的文件存储在目录文件存储在目录 path/myclass/graphics 下
35、。下。包层次的根目录包层次的根目录path是由环境变量是由环境变量CLASSPATH来确来确定的。定的。package myclass.graphics;class Square;class Circle;class Triangle;Square.java第35页,此课件共36页哦 编译和运行包编译和运行包在前面在前面Square.java中已定义了中已定义了myclass.graphics,编译时可以采用如下方式:,编译时可以采用如下方式:javac-ddestpathSquare.java则编译器会自动在则编译器会自动在destpath目录下建立子目录目录下建立子目录myclass/graphics,并将生成的,并将生成的.class文件都放文件都放到到destpath/myclass/graphics下。下。destpath应应该是环境变量该是环境变量CLASSPATH中的一个。中的一个。第36页,此课件共36页哦
限制150内