《第6章继承和多态.ppt》由会员分享,可在线阅读,更多相关《第6章继承和多态.ppt(36页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第6章继承和多态现在学习的是第1页,共36页学习目标学习目标继承可以有效地组织程序结构,明确类之间的继承可以有效地组织程序结构,明确类之间的关系,充分利用已有的类来创建新类,以完成关系,充分利用已有的类来创建新类,以完成更复杂的设计开发。多态则可以统一多个相关更复杂的设计开发。多态则可以统一多个相关类对外的接口,并在运行时根据不同的情况执类对外的接口,并在运行时根据不同的情况执行不同的操作,提高类的抽象度和灵活性。本行不同的操作,提高类的抽象度和灵活性。本章的学习目标就是掌握继承和多态。章的学习目标就是掌握继承和多态。现在学习的是第2页,共36页本章重点本章重点继承继承多态多态抽象类抽象类接口
2、接口包包现在学习的是第3页,共36页当一个类拥有另一个类的数据和操作时,当一个类拥有另一个类的数据和操作时,就称这两个类之间具有继承关系,被继承就称这两个类之间具有继承关系,被继承的类称为的类称为父类父类或或超类超类,继承的类称为,继承的类称为子类子类。一个父类可以同时拥有多个子类,该父类一个父类可以同时拥有多个子类,该父类实际上是所有子类的公共成员变量和公共实际上是所有子类的公共成员变量和公共方法的集合,而子类是父类的特殊化,可方法的集合,而子类是父类的特殊化,可对公共成员变量和方法在功能、内涵方面对公共成员变量和方法在功能、内涵方面加以扩展和延伸。加以扩展和延伸。现在学习的是第4页,共36
3、页面向对象的继承特性中,还有一个关于单面向对象的继承特性中,还有一个关于单继承和多继承的概念。继承和多继承的概念。单继承是指任何类都只有一个父类。单继承是指任何类都只有一个父类。多继承是指一个类可以有一个以上的父类,它多继承是指一个类可以有一个以上的父类,它静态数据和操作从所有这些父类中继承的。静态数据和操作从所有这些父类中继承的。Java只支持单重继承,但支持界面,一个只支持单重继承,但支持界面,一个类可以实现多个界面。利用界面可以得到类可以实现多个界面。利用界面可以得到多继承的优点,又没有多继承混乱、复杂多继承的优点,又没有多继承混乱、复杂的问题。的问题。现在学习的是第5页,共36页Jav
4、a继承:创建子类继承:创建子类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);classUniv
6、ersityStudentextendsStudent/定义子类定义子类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.成员变量的继承成员变量的继承子类重新定义一个从父类那里继承来的成员变量变量完全子类重新定义一个从父类那里继承来的成员变量变量完全相同的变量,称为成员变量的隐藏。相同的变量,称为成员变量的隐藏
8、。3.方法的覆盖方法的覆盖方法的覆盖是指子类重定义从父类继承来的一个同名方法,此时方法的覆盖是指子类重定义从父类继承来的一个同名方法,此时子类将清除父类方法的影响。子类将清除父类方法的影响。注意注意:子类在重新定义父类已有的方法时,应保持与父类完全子类在重新定义父类已有的方法时,应保持与父类完全相同的方法头声明,即应与父类有完全相同的方法名、相同的相同的方法头声明,即应与父类有完全相同的方法名、相同的参数表和相同的返回类型。参数表和相同的返回类型。现在学习的是第8页,共36页【例例】成员变量的隐藏和方法的覆盖示例。成员变量的隐藏和方法的覆盖示例。classSuperClassintx;void
9、setX()x=0;classSubClassextendsSuperClassintx;/成员变量的隐藏成员变量的隐藏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页重写方法的调用规则重写方法的调用规则对于重
14、写的方法,对于重写的方法,Java运行时系统根据调用该运行时系统根据调用该方法的实例的类型来决定选择哪个方法调用。方法的实例的类型来决定选择哪个方法调用。对于类的一个实例,如果子类重写了父类的方对于类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法。如果子类法,则运行时系统调用子类的方法。如果子类继承了父类的方法继承了父类的方法(未重未重),则运行时系统调用,则运行时系统调用父类的方法。因此,一个对象可以通过引用子父类的方法。因此,一个对象可以通过引用子类的实例来调用于类的方法。类的实例来调用于类的方法。现在学习的是第15页,共36页【例例6-5】重写方法的调用规则示例。】重写
15、方法的调用规则示例。classAvoidcallme()System.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页【例例】重重载载实实现现多多态态性性举举例例。该该类类中中定定义义了了矩矩形形,用用四四个个实实例例变变量量来来定定义义
18、这这个个矩矩形形的的左左上上角角和和右右下下角角的的坐坐标标,x1、y1、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,Pointbot
19、tomRight)x1=topLeft.x;y1=topLeft.y;x2=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.buildR
20、ect(25,25,50,50);rect.printRect();System.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
22、页,共36页【例例】抽象类举例。抽象类举例。abstractclassAabstractvoidcallme();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页接口是用
24、来实现类间多重继承功能的结构接口是用来实现类间多重继承功能的结构.在在Java中,出于简化程序结构的考虑,不支持类间的多重继中,出于简化程序结构的考虑,不支持类间的多重继承而只支持单重继承,即一个类至多只能有一个直接父类。承而只支持单重继承,即一个类至多只能有一个直接父类。接口的实现功能比多重继承更强接口的实现功能比多重继承更强接口把方法的定义和类的层次区分开来,通过它可以在运行时动接口把方法的定义和类的层次区分开来,通过它可以在运行时动态地定位所调用的方法;态地定位所调用的方法;同时,也可以实现同时,也可以实现“多重继承多重继承”,且一个类可以实现多个接口。,且一个类可以实现多个接口。正是这
25、些机制使得接口提供了比多重继承更简单,更灵活,而且正是这些机制使得接口提供了比多重继承更简单,更灵活,而且更强健的功能。更强健的功能。现在学习的是第25页,共36页1.接口的定义接口的定义publicinterface接口名接口名extends接口列表接口列表/常量定义和方法定义常量定义和方法定义public指明任意类均可以使用这个接口。在缺省情况下,指明任意类均可以使用这个接口。在缺省情况下,只有与该接口定义在同一个包中的类才可以访问这个接只有与该接口定义在同一个包中的类才可以访问这个接口。口。extends子句与类声明中的子句与类声明中的extends子句基本相同,不子句基本相同,不同的是
26、一个接口可以有多个父接口,用逗号隔开,而一个同的是一个接口可以有多个父接口,用逗号隔开,而一个类只能有一个父类。子接口继承父接口中所有常量和方法。类只能有一个父类。子接口继承父接口中所有常量和方法。现在学习的是第26页,共36页接口体中包括常量定义和方法定义,其格式如下所示:接口体中包括常量定义和方法定义,其格式如下所示:typeconstantName=Value;returnTypemethodName(paramList);在接口中定义的常量可以被用来实现该接口的多个类共在接口中定义的常量可以被用来实现该接口的多个类共享,与享,与C语言中的语言中的const定义常量是相似的。定义常量是相
27、似的。在接口中定义的常量具有在接口中定义的常量具有public、final、static的属的属性。性。接口中只进行方法的声明,而不提供方法的实现,接口中只进行方法的声明,而不提供方法的实现,所以,方法定义没有方法体,且用分号所以,方法定义没有方法体,且用分号(;)结尾。在结尾。在接口中声明的方法具有接口中声明的方法具有public和和abstract属性。属性。另外,如果在子接口中定义了和父接口同名的常量或另外,如果在子接口中定义了和父接口同名的常量或相同的方法,则父接口中的常量被隐藏,方法被覆盖。相同的方法,则父接口中的常量被隐藏,方法被覆盖。现在学习的是第27页,共36页例:例:inte
28、rfaceCollectionintMAX_NUM=100;voidadd(ObjectobjAdd);voiddelete(ObjectobjDelet);Objectfind(ObjectobjFind);intcurrentCount();接口定义中声明了一个常量和四个方法。这个接口可接口定义中声明了一个常量和四个方法。这个接口可以由队列、堆栈、链表等来实现。以由队列、堆栈、链表等来实现。现在学习的是第28页,共36页2.接口的实现接口的实现接口的声明仅仅给出了抽象方法,要具体地接口的声明仅仅给出了抽象方法,要具体地实现接口所规定的功能,则需某个类为接口实现接口所规定的功能,则需某个类为
29、接口中的抽象方法定义实在的方法体,这就称为中的抽象方法定义实在的方法体,这就称为接口的实现接口的实现。在类的声明中,用在类的声明中,用implements句子表示一句子表示一个类将要实现某个接口,在类体中可以引用个类将要实现某个接口,在类体中可以引用接口中定义的常量,而且必须实现接口中定接口中定义的常量,而且必须实现接口中定义的所有方法。一个类可以实现多个接口,义的所有方法。一个类可以实现多个接口,在在implements子句中用逗号分隔。子句中用逗号分隔。现在学习的是第29页,共36页【例例】接接口口的的实实现现:在在类类FIFOQueue中中实实现现上上面面所所定定义义的的接接口口coll
30、ection。classFIFOQueueimplementscollectionvoidadd(Objectobj).voiddelete(Objectobj).Objectfind(Objectobj).intcurrentCount.现在学习的是第30页,共36页注意:注意:在类中实现接口所定义的方法时,方法的声明在类中实现接口所定义的方法时,方法的声明必须与接口中所定义的完全一致。必须与接口中所定义的完全一致。在类中实现接口所定义的方法时,必须显式地在类中实现接口所定义的方法时,必须显式地使用使用publicpublic修饰符,否则将被系统警告为缩小修饰符,否则将被系统警告为缩小了接口
31、中定义的方法的访问控制范围。了接口中定义的方法的访问控制范围。抽象类可以不实现接口的抽象方法,而非抽象抽象类可以不实现接口的抽象方法,而非抽象类必须实现接口中的所有方法。类必须实现接口中的所有方法。现在学习的是第31页,共36页包包利用利用Java语言开发实际系统时,可以利用语言开发实际系统时,可以利用“包包”来来管理类。包是类和接口的集合,为了方便编程和管管理类。包是类和接口的集合,为了方便编程和管理,通常把需要在一起工作的类放在一个包里。理,通常把需要在一起工作的类放在一个包里。为为Java创建一个源码文件的时候,它通常叫做一个创建一个源码文件的时候,它通常叫做一个“编编辑单元辑单元”,每
32、个编辑单元必须有一个以,每个编辑单元必须有一个以java结尾的名结尾的名字。字。缺省情况下,系统为每个缺省情况下,系统为每个.java源文件创建一个无名包,源文件创建一个无名包,该文件中定义的所有类都隶属于该包,但由于该包该文件中定义的所有类都隶属于该包,但由于该包无名字,所以不能被其它包引用。为了解决这个问无名字,所以不能被其它包引用。为了解决这个问题,就要创建有名包。题,就要创建有名包。现在学习的是第32页,共36页标准的标准的Java包列表包列表包功能描述java.applet包含一些用于创建Java小应用程序的类java.awt包含一些编写平台无关的图形用户界面(GUI)应用程序的类。
33、它包含几个子包,包括java.awt.peer和java.awt.imagejava.io包含一些用作输入输出(I/O)处理的类。数据流就包含在这里java.1ang包含一些基本Java类。java.1ang是被隐式地引入的,所以用户不必引入它的类包含用于建立网络连接的类。与java.io同时使用以完成与网络有关的读和写java.util包含一些其他的工具和数据结构,如编码、解码、向量和堆栈等现在学习的是第33页,共36页包的创建包的创建用用package关键字创建包,而且该语句是关键字创建包,而且该语句是.java源文件的第源文件的第一个语句,前面不能有注释和空格。格式为一个语句,前面不能有
34、注释和空格。格式为:package包名;包名;例如:例如:packageSubClass;packageMyClass.SubClass;实际上,创建包就是在当前目录下创建一个子目录实际上,创建包就是在当前目录下创建一个子目录SubClass,以便存放这个包中包含的所有类的,以便存放这个包中包含的所有类的.class文文件。件。上面的第二个语句中的上面的第二个语句中的“.”代表了目录分隔符。即包中的类代表了目录分隔符。即包中的类放在当前目录下的放在当前目录下的SubClass子目录下的子目录下的MyClass子目录子目录下。下。现在学习的是第34页,共36页package myclass.gr
35、aphics;这条语句指定这个包中的文这条语句指定这个包中的文件存储在目录件存储在目录 path/myclass/graphics 下。下。包层次的根目录包层次的根目录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页