您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 面向对象程序设计-Java语言05
第5章消息、继承、封装与多态世界是由各种各样的对象组成,对象之间的相互作用形成了这个丰富多彩的世界。在面向对象的系统中,对象之间的相互作用是通过一个对象向另一个对象发送消息的方式体现的。多个对象之间通过传递消息来请求或提供服务,从而使一个软件具有更强大的功能。封装是指类的设计者只是为类的使用者提供类的可以访问的部分(包括类的数据成员和成员方法),而把类中的其他成员隐藏起来,用户不能访问。继承是面向对象程序设计的一个重要特征,它是通过一个类派生子类来实现的,这种结构对充分利用已有的类来创建更复杂的类,实现代码的复用具有重要意义。多态是面向对象的程序中同名不同方法共存的现象,引入多态机制可以提高类的抽象度和封闭性,统一类的对外接口。通过本章的学习,读者将深入了解类的这些特性。本章主要内容5.1消息5.2继承5.3抽象类、接口和包5.4封装5.5多态5.1消息•在面向对象的系统中,对象间的相互作用是通过一个对象向另一个对象发送消息的方式来体现的。消息就是数据成员和成员方法的引用。–消息的概念•消息就是向对象发出服务请求,是对数据成员和成员方法的引用。•消息的性质:(1)同一对象可接收不同形式的多个消息,产生不同的响应。(2)相同形式的消息可以发送给不同对象,所做出的响应可以是截然不同的。(3)消息的发送可以不考虑具体的接收者,对象可以响应消息,也可以对消息不予理会,对消息的响应并不是必须的。–公有消息和私有消息•对象之间的消息传递称为公有消息;而对象内部数据成员或成员方法之间的调用称为私有消息。–【例5.1】公有消息和私有消息示例。5.2继承继承是面向对象程序设计的又一种重要手段,在面向对象程序设计中,采用继承机制可以有效地组织程序结构,设计系统中的类,明确类之间的关系,充分利用已有的类来创建更复杂的类,大大提高程序开发的效率,提高代码的复用率,降低维护的工作量。–继承的概念•继承所表达的就是一种对象类之间的相交关系,它使得某类对象可以继承另外一类对象的数据成员和成员方法。•继承避免了对一般类和特殊类之间共同特征进行的重复描述,运用继承原则使得系统模型比较简练也比较清晰。父类与子类之间的关系如图所示:学生小学生中学生大学生研究生留学生初中生专科生高中生本科生硕士生博士生–继承的特征(1)继承关系是传递的。(2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。(3)提供软件复用功能。(4)通过增强一致性来减少模块间的接口和界面,大大增加程序的易维护性。(5)提供多继承机制。–继承的实现•在Java程序设计中,继承是通过extends关键字来实现的。在定义类时使用extends关键字指明新定义类的父类,新定义的类称为指定父类的子类,就在两个类之间建立了继承关系。这个新定义的子类可以从父类那里继承所有非private的属性和方法作为自己的成员。实际上,在定义一个类而不给出extends关键字及父类名时,默认这个类是系统类Object的子类。1.数据成员的继承:子类可以继承父类的所有非私有的数据成员。【例5.2】数据成员继承示例。2.数据成员的隐藏:在子类中重新定义一个与父类中已定义的数据成员名完全相同的数据成员,即子类拥有了两个相同名字的数据成员,一个是继承父类的,另一个是自己定义的。当子类引用这个同名的数据成员时,默认操作是引用它自己定义的数据成员,而把从父类那里继承来的数据成员“隐藏”起来。当子类要操作继承自父类的同名数据成员时,可使用关键字super引导。【例5.3】数据成员隐藏示例。3.成员方法的继承:子类可以继承父类的非私有成员方法。【例5.4】成员方法继承示例。4.成员方法的覆盖:子类可以重新定义与父类同名的成员方法,实现对父类方法的覆盖。方法的覆盖与数据成员的隐藏的不同之处在于:子类隐藏父类的数据成员只是使之不可见,父类同名的数据成员在子类对象中仍然占有自己独立的内存空间;而子类方法对父类同名方法的覆盖将清除父类方法占用的内存,从而使父类方法在子类对象中不复存在。【例5.5】成员方法覆盖示例。–this与super1.this的使用场合。在一些容易混淆的场合,例如,成员方法的形参名与数据成员名相同,或者成员方法的局部变量名与数据成员名相同时,在方法内借助this来明确表示引用的是类的数据成员,而不是形参或局部变量,从而提高程序的可读性。简单地说,this代表了当前对象的一个引用,可将其理解为对象的另一个名字,通过这个名字可以顺利地访问对象、修改对象的数据成员、调用对象的方法。归纳起来,this的使用场合有下述3种:(1)用来访问当前对象的数据成员,其使用形式如下:this.数据成员(2)用来访问当前对象的成员方法,其使用形式如下:this.成员方法(参数)(3)当有重载的构造方法时,用来引用同类的其他构造方法,其使用形式如下:this(参数)【例5.6】this使用示例。【例5.7】使用this示例。2.super的使用场合。super表示的是当前对象的直接父类对象,是当前对象的直接父类对象的引用。super的使用方法有3种:(1)用来访问直接父类隐藏的数据成员,其使用形式如下:super.数据成员(2)用来调用直接父类中被覆盖的成员方法,其使用形式如下:super.成员方法(参数)(3)用来调用直接父类的构造方法,其使用形式如下:super(参数)【例5.8】super使用示例。5.3抽象类、接口和包抽象类体现数据抽象的思想,是实现程序多态性的一种手段。接口则是Java中实现多重继承的唯一途径。包是一个更大的程序单位,主要实现软件复用。–抽象类•假设要编写一个计算圆、三角形和矩形面积与周长的程序,若按前面所学的方式编程,必须定义4个类:圆类、三角形类、矩形类和使用前3个类的公共类,它们之间没有继承关系。程序写好后虽然能执行,但从程序的整体结构上看,3个类之间的许多共同属性和操作在程序中没有很好地利用,•如图所示,致使重复编写代码,降低了程序的开发效率,且使出现错误的机会增加。圆类圆心坐标半径计算面积计算周长三角形类底边长高计算面积计算周长矩形类长宽计算面积计算周长分析上面例子中的3个类,可以看到这3个类都要计算面积与周长,虽然公式不同但目标相同。因此,可以为这3个类抽象出1个父类,在父类里定义圆、三角形和矩形3个类共同的数据成员及成员方法,把计算面积与周长的成员方法名放在父类给予说明,而具体的计算公式再在子类中实现。这样,通过父类就大概知道子类所要完成的任务,而且,这些方法还可以应用于求解平行四边形、梯形等图形的周长与面积,如图5-4所示。这种结构就是抽象类的概念。抽象类抽象方法梯形类上、下底边长高抽象方法圆类圆心坐标半径计算面积计算周长三角形类底边长高计算面积计算周长矩形类长宽计算面积计算周长抽象类刻画了公有行为的特征,并通过继承机制传送给它的派生类。在抽象类中定义的方法称为抽象方法,这些方法只有方法头的声明,而用一个分号来代替方法体的定义,即只定义成员方法的接口形式,而没有具体操作,只有派生类对抽象成员方法的重定义才能真正实现与该派生类相关的操作。在各子类继承了父类的抽象方法之后,再分别用不同的语句和方法体来重新定义它,形成若干个名字相同、返回值相同、参数列表相同、目的一致但是具体实现有一定差别的方法。抽象类中定义抽象方法的目的是实现一个接口,多种方法的原理,即所有的子类对外都呈现一个相同名字的方法。抽象类是它的所有子类公共属性的集合,是包含一个或多个抽象方法的类。使用抽象类的一大优点就是可以充分利用这些公共属性来提高开发和维护程序的效率。对于抽象类与抽象方法的限制如下:(1)凡是用abstract修饰符修饰的类被称为抽象类。凡是用abstract修饰符修饰的成员方法被称为抽象方法。(2)抽象类中可以有零个或多个抽象方法,也可以包含非抽象方法。(3)抽象类中可以没有抽象方法,但是,有抽象方法的类必须是抽象类。(4)对于抽象方法来说,在抽象类中只指定其方法名及其类型,而不书写其实现代码。(5)抽象类可以派生子类,在抽象类派生的非抽象子类中必须实现抽象类中定义的所有抽象方法。(6)抽象类不能创建对象,创建对象的工作由抽象类派生的非抽象子类来实现。(7)如果父类中已有同名的abstract方法,则子类中就不能再有同名的抽象方法。(8)abstract不能与final并列修饰同一个类。(9)abstract不能与private、static、final或native并列修饰同一个方法。(10)abstract类中不能有private的数据成员或成员方法。【例5.9】抽象类应用。注意:在上例中,只能在C5_9类中main方法中定义3个子类的对象,使它们称为main方法的局部对象,而不能将它们定义在main方法之外,因为非static方法是不能在static方法中被引用的,而方法中的局部变量不能带修饰符,它们不受此限制。–接口多重继承是指一个子类可以有多个直接父类,该子类可以全部或部分继承所有直接父类的数据成员及成员方法。在面向对象的程序设计语言中,有些语言(如C++)提供了多继承机制。而Java出于安全性、简化程序结构的考虑,不支持类间的多继承而只支持单继承。然而在解决实际问题的过程中,在很多情况下仅仅依靠单继承不能将复杂的问题描述清楚。为了Java程序的类间层次结构更加合理,更符合实际问题的本质要求,Java语言提供接口来实现多重继承机制。1.声明接口,格式如下:[修饰符]interface接口名[extends父接口名列表]{常量数据成员声明抽象方法声明}常量数据成员前可以有也可没有修饰符,其默认的修饰符是publicfinalstatic。接口中方法默认的修饰符为publicabstract。从上面的格式可以看出,定义接口与定义类非常相似。实际上完全可以把接口理解成为一种特殊的类,接口是由常量和抽象方法组成的特殊类。一个类只能有一个父类,但是它可以同时实现若干个接口。这种情况下,如果把接口理解成特殊的类,那么这个类利用接口实际上就获得了多个父类,即实现了多重继承。接口定义仅仅是实现某一特定功能的一组功能的对外接口和规范,而不能真正地实现这个功能,这个功能的真正实现是在“继承”这个接口的各个类中完成的,要由这些类来具体定义接口中各抽象方法的方法体。因而在Java中,通常把对接口功能的“继承”称为“实现”。2.定义接口注意事项(1)接口定义用关键字interface,而不是用class。(2)接口中定义的数据成员全是publicfinalstatic成员,即常量。(3)接口中没有自身的构造方法,所有成员方法都是publicabstract方法,即抽象方法。(4)接口也具有继承性,可以通过extends关键字声明该接口的父接口。一个类要实现接口时,即一个类要调用多个接口时,要注意以下几点。:(1)在类中,用implements关键字就可以调用接口。一个类可以调用多个接口,这时,在implements后用逗号隔开多个接口的名称。(2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现接口的所有抽象方法,即为所有抽象方法定义方法体,而且方法头部分应该与接口中的定义完全一致,即有完全相同的返回值和参数列表。(3)如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。但是对于这个抽象类任何一个非抽象的子类而言,它们父类所实现的接口中的所有抽象方法以及自身所实现接口中的抽象方法都必须有实在的方法体。这些方法体可以来自抽象的父类,也可以来自子类自身,但是不允许存在未被实现的接口方法。这主要体现了非抽象类中不能存在抽象方法的原则。(4)接口的抽象方法的访问限制符都已指定为public,所以类在实现方法时,必须显式地使用public修饰符,否则将被系统警告为缩小了接口中定义的方法的访问控制范围。【例5.10】将例5.9改写为接口程序。【例5.11】将例5.10改写为既有继承类又有接口的程序。–包•在Java程序中,如果要想使一个类在多个场合下反复使用,可以把它存
本文标题:面向对象程序设计-Java语言05
链接地址:https://www.777doc.com/doc-3968305 .html