JAVA语言项目3JAVA面向对象编程_第1页
JAVA语言项目3JAVA面向对象编程_第2页
JAVA语言项目3JAVA面向对象编程_第3页
JAVA语言项目3JAVA面向对象编程_第4页
JAVA语言项目3JAVA面向对象编程_第5页
已阅读5页,还剩190页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

面向对象程序设计(ObjectOrientedProgramming)简称(OOP),是一种新兴的程序设计方法,其基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计。类是Java程序中的最基本构件,即Java程序是一大堆类的集合。,下一页,项目3Java面向对象编程,项目3Java面向对象编程,3.1项目概述3.2项目目的3.3项目支撑知识3.4项目实施3.5项目总结3.6扩展训练,3.1项目概述,在本项目中主要学习面向对象程序设计的基本思想和面向对象的概念,类的定义,成员变量和成员方法的定义及使用,对象的创建和使用,类的继承和多态,访问控制和修饰符,抽象类、接口和包的声明及实现方法。,返回,3.2项目目的,掌握创建和使用类对象、使用包的基本方法。.理解继承和复用的概念。.了解接口的声明及实现方法。.理解多态性是如何扩充和维护系统性能。,返回,3.3项目支撑知识,面向对象是一种新兴的程序设计方法,或者是一种新的程序设计规范(paradigm),其基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。开发一个软件是为了解决某些问题,这些问题所涉及的业务范围称作该软件的问题域。其应用领域不仅仅是软件,还有计算机体系结构和人工智能等。在面向过程的设计中,程序员只限于使用语句构建软件,即把语句集合起来组成方法(后面称之为函数或过程)。,下一页,返回,3.3项目支撑知识,如建筑师,只限于使用木、水、土等原材料搭建房屋,工作多,效率低。并且在房子需重新翻盖时,所有的原材料将没有用。但如果将水、土先烧成砖,木先制成门、窗等,盖房时使用砖、门、窗成形的原料,只需考虑不同型号的门、窗放的位置。即使已建成的房屋,需要重新翻盖,也不用从零开始,砖、门、窗等原材料都可重新再用,可提高工作效率,降低成本。这一类工程设计类似于面向对象的程序开发。,上一页,下一页,返回,3.3项目支撑知识,3.3.1项目开发背景知识1面向对象的概述一、面向对象的基本概念1.对象的基本概念对象是代表现实生活中的实物的软件编程实体,比如说银行账号,计算机用户,用户介面上的按钮,窗口菜单等。对象是由它们的状态和行为定义的。例如,一个银行账号拥有一种状态,诸如当前的收支状况,账户的所有入,允许的最小交易额等,而它的行为则包括提取,存入,收支平衡等。,上一页,下一页,返回,3.3项目支撑知识,对象具有两方面的含义:在现实世界中,是客观世界中的一个实体;在计算机世界中,作为真实世界的抽象,由一个数据集以及对该数据集的操作组成。2.类的基本概念类:具有共同属性和行为的对象集合。类与对象的关系:类是对象的抽象,对象是类的实例。类是一个实体,它定义了一个对象的运行方式以及在对象被创建或者说实例化的时候所包含的数据。类的作用就像一个模板,一个或者多个对象可以依照它来创建。,上一页,下一页,返回,3.3项目支撑知识,3.消息消息:对象之间相互请求或相互协作的途径,是要求某个对象执行某项功能操作的规格说明。消息内容:通常包含接收方及请求接收方完成的功能信息。发送方:发出消息,请求接收方响应。接收方:收到消息后,经过解释,激活方法,予以响应。消息的性质:同一对象可接收不同形式的多个消息,产生不同的响应。同一个消息可以发给不同的对象,所做出的响应可以截然不同;发送方不需要知道接收方如何对请求予以响应的。,上一页,下一页,返回,3.3项目支撑知识,消息就是向对象发出的服务请求,它应该包含下述信息:提供服务的对象标识、服务标识、输入信息和回答信息。服务通常被称为方法或函数。举例说明:对象是具有某种特性和某种功能的东西。将同一种类型的对象归为一个类,以类的形式描述对象的状态和功能。例如,汽车是一类,其中如小轿车、中型面包车、大货车等,可认为是对象。类是对象的抽象,对象是类的实例。那么汽车就是Java中的类,判定某一对象是否是汽车,要看它是否具有这些属性,而自行车不能叫汽车,因为它不具有发动机属性。,上一页,下一页,返回,3.3项目支撑知识,在面向对象的程序设计中,将类的特征和行为分别命名为属性和方法。例如,定义“电视机”这样一个类,如图3-1所示。电视机的属性和方法定义如图3-2所示。一个类中定义的方法可以被该类的对象调用,对象方法的每一调用被称作发送一个消息(message)给对象。对象间是相互独立的,通过发送消息相互影响。采用消息可以让对象的行为通过它的方法来表达。一个消息由三部分组成:消息目标对象;执行方法的名字;,上一页,下一页,返回,3.3项目支撑知识,执行方法所需要的参数(parameters)。(因Java是一个对象化的语言,对象也常被用来当作参数传递)。方法。表明对象所具有的行为,是对象与外界的接口。一个对象的行为是由它上面的操作定义的,这些操作被叫做方法。方法可以改变一个对象的状态,创建新对象,实现实用的功能等。作用:改变对象的属性,返回对象的属性。二、面向对象的特点,上一页,下一页,返回,3.3项目支撑知识,(1)封装。隐藏实现细节。例如,对象可以看作是数据及作用在这些数据上的封装体,它通过一个接口与外部进行交互,因此封装使得对象的内部实现与外部接口分离开来。这样,改变对象的内部实现并不影响使用这个对象的其他对象或应用。这种封装性也体现了一种抽象和信息隐蔽。(2)继承性。继承是指一个子类继承父类(或称为基类)的特征(数据结构和方法)。在继承一个父类时,可以在子类中增加新的数据结构和方法,也可以重定义从父类中继承下来的方法。父类的特征并不受子类的影响,反之,在理想情况下,父类的内部实现的变化不会影响子类。,上一页,下一页,返回,3.3项目支撑知识,当然,一个子类可有多个父类,这种情况称为多继承(C+语言支持多继承)。继承带来的好处是软件的复用,使用继承可以在已有软件构件的基础上构造新的软件,从而提高软件的生产率并保证软件的质量。简而言之,继承性是父类和子类之间共享数据和方法的机制;继承性具有传递性;继承性包括单继承和多重继承。继承性具有以下作用:使软件系统具有开放性;更好地进行抽象与分类;增强代码的重用率;提高可维护性。,上一页,下一页,返回,3.3项目支撑知识,(3)多态性。不同的对象收到同一个消息可产生完全不同的效果,这一现象叫做多态。多态的原意是指一个实体多个形态。在面向对象程序设计中主要是指变量多态和方法多态,变量多态是指同一个变量在运行时刻标识(表示)不同类型的对象,而方法多态主要是指同一个方法做不一样的动作,例如不同类的对象接受相同的消息(方法调用),但有不一样的响应动作。多态使得消息发送者能给一组具有公共接口的对象发送相同的消息,接收者作出相应的动作。变量多态是方法多态的基础。多态通常与语言的动态绑定(DynamicBinding)机制有关。,上一页,下一页,返回,3.3项目支撑知识,多态的效果:用户发送一个通用的消息,而实现的细节则由接收对象自行决定。多态性的作用:增强了操作的透明性、可理解性和可扩展性;增强了软件的灵活性和重用性。三、面向对象的优点为什么现代程序设计语言会向面向对象编程靠拢?这是因为面向对象编程具备了几个优点,比如:代码维护方便、可扩展性好、支持代码重用技术等。这些优点是过程编程语言所不具备的。下面我们就来谈谈面向对象技术的这些优点。,上一页,下一页,返回,3.3项目支撑知识,(1)维护简单。模块化是面向对象编程中的一个特征。实体被表示为类和同一名字空间中具有相同功能的类,可以在名字空间中添加一个类而不会影响该名字空间的其他成员。(2)可扩充性。面向对象编程从本质上支持扩充性。如果有一个具有某种功能的类,就可以很快地扩充这个类,创建一个具有扩充的功能的类。(3)代码重用。,上一页,下一页,返回,3.2项目支撑知识,由于功能是被封装在类中的,并且类是作为一个独立实体而存在的,提供一个类库就非常简单了。事实上,任何一个编程语言的程序员都可以使用类库,类库提供了很多的功能。更令人高兴的是,可以通过提供符合需求的类来扩充这些功能。3.3.2项目开发背景知识2类的定义进行Java程序设计,实际上就是定义类的过程。一个Java源程序文件往往是由许多个类组成的。从用户的角度看,Java源程序中的类分为两种。,上一页,下一页,返回,3.3项目支撑知识,(1)系统定义的类,即Java类库,它是系统定义好的类。类库是Java语言的重要组成部分。Java语言由语法规则和类库两部分组成,语法规则确定Java程序的书写规范;类库则提供了Java程序与运行它的系统软件(Java虚拟机)之间的接口。Java类库是一组由它的发明者SUN公司以及其他软件开发商编写好的Java程序模块,每个模块通常对应一种特定的基本功能和任务,且这些模块都是经过严格测试的,因而也总是正确有效的。当自己编写的Java程序需要完成其中某一功能的时候,就可以直接利用这些现成的类库,而不需要一切从头编写,这样不仅可以提高编程效率,也可以保证软件的质量。,上一页,下一页,返回,3.3项目支撑知识,(2)用户自己定义的类。系统定义的类虽然实现了许多常见的功能,但是用户程序仍然需要针对特定问题的特定逻辑来定义自己的类。用户按照Java的语法规则,把所研究的问题描述成Java程序中的类,以解决特定问题。一个类的定义应包含两部分:类的声明和类的实体。一、类的声明类声明包括关键字class、类名及类的属性。类名必须是合法的标识符,类的属性为一些可选的关键字。其声明格式如下,)内参数为可选项。,上一页,下一页,返回,3.3项目支撑知识,其中,修饰符public,abstract,final说明了类的属性,className为类名,superclassName为类的父类的名字,interfaceNameList为类所实现的接口列表。修饰符含义如下:abstract:声明该类不能被实例化。final:声明该类不能被继承,即没有子类。classclassname:关键字class告诉编译器表示类的声明以及类名是className。,上一页,下一页,返回,3.3项目支撑知识,extendssuperclassname:extends语句扩展superclassName为该类的父类。implementsinterfaceNameList:声明类可实现一个或多个接口,可以使用关键字implements并在其后面给出由类实现的多个接口名字列表,各接口间以逗号分隔。二、成员变量成员变量的声明方式如下:,上一页,下一页,返回,3.3项目支撑知识,其中,/成员变量static:静态变量(类变量);相对于实例变量。final:常量。transient:暂时性变量,用于对象存档。volatile:贡献变量,用于并发线程的共享。三、成员方法方法的实现包括两部分内容:方法声明和方法体。,上一页,下一页,返回,3.3项目支撑知识,方法声明中的限定词的含义。static:类方法,可通过类名直接调用。abstract:抽象方法,没有方法体。final:方法不能被重写。native:集成其他语言的代码。Synchronized:控制多个并发线程的访问。,上一页,下一页,返回,3.3项目支撑知识,【例3-1】一个完整的类定义如下。,上一页,下一页,返回,3.3项目支撑知识,3.3.3项目开发背景知识3成员变量和成员方法一、成员变量成员变量是类定义中的重要组成部分,从不同的角度区分,它可以分为多种类型。1.从变量定义的位置分根据变量定义的位置划分,变量可以分为全局变量和局部变量。,上一页,下一页,返回,3.3项目支撑知识,全局变量:定义在类中任何方法的外部,其作用范围为该变量所属的整个类。局部变量:定义在类中某一方法的内部,其作用范围为该变量定义的地方起,至所属方法结束的地方为止。【例3-2】测试全局变量的操作。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,程序运行结果如图3-3所示。从此例我们可以看出,全局变量作用于其所在的整个类,在确保全局变量定义在类中任何方法的外部的前提下,它可以被随处安放,即使它的定义处在该全局变量的使用处之后。如例子中的全局变量vara,varb的定义语句,完全可以把其安排在类的prim()方法定义体的右括号之后,程序运行的效果相同,这一点是与C/C+所不同的。【例3-3】测试局部变量的操作。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,运行结果如图3-4所示。2.从变量的数据类型分根据变量所属的数据类型划分,变量可以分为基本类型变量和对象类型变量。所谓基本类型变量,就是指我们在第二章中讲述的8种基本数据类型,如int,double等,而由系统类库或者自定义类定义的变量,则为对象类型变量。这正如我们讲数据类型时对应的,基本类型对应的是基本变量,在一个类中又被称为成员变量。对象类型对应的就是对象类型变量,在类中又可以被称为实例变量。【例3-4】基本类型变量和对象型变量测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,程序运行结果如图3-5所示。,上一页,下一页,返回,3.3项目支撑知识,【例3-5】简单数据类型与引用数据的区别。,上一页,下一页,返回,3.3项目支撑知识,程序运行结果如图3-6所示。,上一页,下一页,返回,3.3项目支撑知识,3.从变量的性质分根据变量的性质划分,可以将变量分为类变量和成员变量。所谓类变量(classvariable),就是用关键字static声明的全局变量,它是属于类本身的,不代表任何对象的状态。所谓成员变量,就是与类变量相对的,没有用static声明的其他变量,它是与具体对象相关的,保持对象的状态。类变量的使用能满足这样的需求,即有时想有一个可以在类的所有实例中共享的变量。比如,这可以用作实例之间交流的基础或追踪已经创建的实例的数量。数值型类变量在进行数值计算时候有其特殊性,即每次参加运算时的初始值为其上次运算的结果值。,上一页,下一页,返回,3.3项目支撑知识,类变量与成员变量的通用调用格式如下。类变量:类名.类变量名成员变量:对象名.成员变量名【例3-6】类变量和成员变量测试,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,程序运行结果如图3-7所示。此例中,设置l对象计数器counter为static型,要注意,若没有为该类变量初始化的话,那系统将为其设置默认值0。二、成员方法的使用成员方法通常用来描述该类对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块。1.成员方法声明在Java程序中,成员方法的声明只能在类中进行,格式如下:,上一页,下一页,返回,3.3项目支撑知识,一修饰返回值的类型成员方法名(形式参数表)throw一异常表说明部分执行语句部分,上一页,下一页,返回,3.3项目支撑知识,成员方法的声明包括成员方法头和方法体两部分,其中:成员方法头确定成员方法的名字、形式参数的名字和类型、返回值的类型、访问限制和异常处理等;方法体由包括在花括号内的说明部分和描述该方法功能实现的执行部分组成,执行部分一般由变量声明语句、赋值语句、流程控制语句、方法调用语句、返回语句等Java允许的各种语句成分组成,是程序设计中最复杂的部分,几乎会用到我们已经学习过的和将要学习的绝大多数内容。,上一页,下一页,返回,3.3项目支撑知识,在成员方法头中:(1)修饰符。修饰符可是public,private,protected等访问权限修饰符,也可以是static,final,native,abstract等非访问权限修饰符。访问权限修饰符指出满足什么条件时该成员方法可以被访问。非访问权限修饰符指明数据成员的使用方法。具体参阅下面有关内容。(2)返回值的类型。返回值的类型用Java允许的各种数据类型关键字(例如,int,float等)指明成员方法返回结果值的数据类型。若成员方法没有返回值,则在返回值的类型处应写上void关键字。,上一页,下一页,返回,3.3项目支撑知识,(3)成员方法名。成员方法名也就是用户遵循标识符定义规则命名的标识符。(4)形式参数表。成员方法可分为带参成员方法和无参成员方法两种。对于无参成员方法来说则无形式参数表这一项,但其后的圆括号不可省略;对于带参成员方法来说,形式参数表指明调用该方法所需要的参数个数、参数的名字及其参数的数据类型,其格式为:(形式参数类型1,形式参数名1,形式参数类型2,形式参数名2,)(5)throws!异常表。它指出当该方法遇到一些方法的设计者未曾想到的异常问题时如何处理。这部分内容将在项目4中作专门介绍。,上一页,下一页,返回,3.3项目支撑知识,2.成员方法引用成员方法的引用可有下述几种方式。方法语句:成员方法作为一个独立的语句被引用。例如,add(a,b)。方法表达式:成员方法作为表达式中的一部分被引用。例如,f3=2+add1(f1,f2)。方法作为参数:一个成员方法作为另一个成员方法的参数被引用。例如,add(a,add1(f1,f2),这里add1()是方法。通过对象来引用:即通过形如“对象名.方法名”的形式来引用对象,如Dane.ShowDog(25,25),这里Dane是对象名,ShowDog是方法名。,上一页,下一页,返回,3.3项目支撑知识,3.形式参数与实际参数一般来说,可通过如下的格式来引用成员方法:成员方法名(实参列表)但在引用时应注意下述问题。对于无参成员方法来说,是没有实参列表的,但方法后的括弧不能省略。对于带参数的成员方法来说,实参的个数、顺序以及它们的数据类型必须与形式参数的个数、顺序以及它们的数据类型保持一致,各个实参间用逗号分隔。实参名与形参名可以相同也可以不同。,上一页,下一页,返回,3.3项目支撑知识,实参也可以是表达式,此时一定要注意使表达式的数据类型与形参的数据类型相同,或者使表达式的类型按Java类型转换规则达到形参指明的数据类型。4.构造方法在类的构造中有一种特殊的成员方法,被称为构造方法。构造方法的应用通常具有明确的目的:给对象进行初始化,即对类中的成员变量赋值,这种初始化动作在new返回新创建对象的引用前完成。构造方法具有如下的明显特点。构造方法的名字与其所属类的类名相同。构造方法是给对象赋初值,没有返回值。,上一页,下一页,返回,3.3项目支撑知识,构造方法不能被程序显式调用,由new构造对象时系统自动调用。构造方法可以有零个或多个形式参数。构造方法可在类中由用户定义,若用户没有定义,系统将自动生成一个空构造方法。构造方法可以通过重载实现不同的初始化方法。【例3-7】构造方法测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,程序运行结果如图3-8所示。,上一页,下一页,返回,3.3项目支撑知识,本例中涉及到了方法的重载,可暂时简单理解为系统依据不同的参数列表调用同名的方法,如代码中catA和catB对象的构造分别调用了不同的Cat类的构造方法。)3.3.4项目开发背景知识4对象的使用当我们创建了一个类,就等同于创建了一种新的数据类型,可以像使用基本数据类型一样地使用类。类定义好之后,我们将用该类定义一个实例,即该类的对象。一、对象的创建创建一个类的对象通常包括三个步骤,即声明对象、建立对象和初始化对象。,上一页,下一页,返回,3.3项目支撑知识,1.声明对象所谓声明对象,就是确定对象的名称,并指明该对象所属的类。声明对象的格式如下:类名对象名表;其中:类名是指对象所属类的名字,它是在声明类时定义的;对象名表是指一个或多个对象名,若为多个对象名时,用逗号进行分隔。声明对象的作用是创建对象空间的管理者。例如:DogdogA,dogB;,上一页,下一页,返回,3.3项目支撑知识,这个语句声明了Dog类的两个对象dogA,dogB,它们可以被用来引用实际的Dog类对象空间,但必须明自此时,dogA和,dogB只是两个将来可以引用真正Dog类实例的对象名,还并不具备具体内存空间。2.建立对象所谓建立对象,实际上就是用Java提供的new关键字为对象分配存储空间。在声明对象时,只确定了对象的名称和它所属的类,并没有为对象分配存储空间,此时对象还不是类的实例。只有通过建立对象这一步,才为对象分配内存,使该对象成为类的实例。建立对象的格式如下:,上一页,下一页,返回,3.3项目支撑知识,对象名=new构造方法();例如:dogA=newDog();也可以在声明对象的同时建立对象,这称为创建一个对象。创建对象的格式如下:类名对象名=new构造方法();例如:DogdogA=newDog();其中:new是Java的关键字,也可将其称为运算符,因为new的作用是建立对象,为对象分配存储空间。执行newDog将产生一个Dog类的对象(具备内存空间)。,上一页,下一页,返回,3.3项目支撑知识,3.初始化对象初始化对象是指由一个类生成一个对象时,为这个对象确定初始状态,即给它的数据成员赋初值的过程,当然,它主要由一些赋值语句组成。例如:由于初始化操作是最常用的操作之一,为简化这一过程,Java还提供了专用的方法来完成它,即前面刚刚介绍的构造方法。对象创建的三个步骤在内存中都起厂相应的变化,如表3-1所示。,上一页,下一页,返回,3.3项目支撑知识,从上表3-1中可以看出,声明对象时仅仅定义一个该类的引用变量,这时候该引用变量的值为null,意为该引用此时与任何实体空间无关。在建立对象阶段,通过new关键字申请了一个Dog类的对象空间,并同时返回厂该空间的首地址,假设该空间首地址为F000,那在执行dogA=newDog();语句时,实际上是把地址值“F000”赋值给了引用变量dogA,注意此时,虽然一个Dog对象已经创建,但该对象内部的两个成员变量weight和height是没有被赋值的。在初始化阶段,我们才真正对这两个成员变量赋具体值。,上一页,下一页,返回,3.3项目支撑知识,二、传值引用与传址引用Java程序中,当变量间发生赋值动作时,涉及到传值引用与传址引用的问题。所谓传值,即指“=”号两端变量各自具有独立的值空间,右端变量把自身的变量值复制给左端变量,这种方式发生在基本数据类型变量间的赋值操作。所谓传址,右端变量把自身引用(管理)的内存空间的首地址复制给左端变量,这样“=”号两端变量共同引用(管理)一个内存空间,这种方式发生在对象变量间的赋值操作。传值引用与传址引用操作相应的内存变化状况如下表3-2所示。,上一页,下一页,返回,3.3项目支撑知识,从上表3-2可以看出,执行intb=a;语句时,基本数据类型变量b具备自身独立的内存空间,该空间内的值是对变量a的值的简单复制;执行DogdogB=dogA时,对象型变量dogB仅仅是复制r对象型变量dogA所引用(管理)的具体对象内存空间的首地址(也即dogA变量本身的值),而不是复制dogA所引用(管理)的具体对象,这样导致对象型变量dogB和dogA具有共同的地址值,也即管理着一个共同的对象内存空间。三、自动垃圾收集机制,上一页,下一页,返回,3.3项目支撑知识,在Java中,对于类对象的创建都需要使用new关键词,它向系统运行时申请指定类的一个对象的内存空间,并把该内存空间的首地址返回。那么当程序中不再需要这些通过new创建的对象时,怎么办呢?大家回想一下,在C/C+里面,有相应的malloc()/free()和new()/delete()两对函数来操作空间申请和释放。而Java中,而无相应的关键词来申请对象空间,而无相应的关键词来删除对象空间。难道Java中只许用户申请空间而不能删除这些空间吗?答案是否定的,其实Java内部提供了一种称为自动垃圾收集的机制来执行此项任务,这也是Java的安全性措施之一。,上一页,下一页,返回,3.3项目支撑知识,Java的自动垃圾收集机制通过多种算法(如引用计数法(ReferenceCountingCollector),Tracing算法(TracingCollector)等)来确定哪些对象空间需要被删除,无须用户主动性地去删除那些通过new申请来的对象空间。虽然Java中不需要也不建议大家去主动释放动态对象空间,但还是提供了主动释放空间的途径,即使用System类的gc()方法。使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求Java的垃圾回收。在命令行中有一个参数-vergosegc可以查看Java使用的堆内存的情况,它的格式如下。【例3-8】gc()方法测试。,上一页,下一页,返回,3.3项目支撑知识,程序运行效果如图3-9所示。,上一页,下一页,返回,3.3项目支撑知识,在这个例子中,一个新的对象被创建,由于它没有使用,所以该对象迅速地变为可达,程序运行后结果为:箭头前后的数据123K和88K分别表示垃圾收集GC前后所有存活对象使用的内存容量,说明有123K-88K=35K的对象容量被回收,括号内的数据1984K为堆内存的总容量,收集所需要的时间是0.0148759秒(这个时间在每次执行的时候会有所不同)。,上一页,下一页,返回,3.3项目支撑知识,3.3.5项目开发背景知识5类的继承和多态一、继承继承是面向对象编程中的重要特性之一。继承允许创建一个通用类,它具有同类事务的一般特征。该类可以被更具体的类所继承,每个具体类都可以添加自己有特色的属性。Java中被继承的类,称为父类(或超类,superClass),继承父类的类,称为子类(或派生类,subclass)。可以把子类看成是父类的一个特殊功能版本,子类继承了父类的所有特征(成员变量和方法)。,上一页,下一页,返回,3.3项目支撑知识,1.创建子类Java中继承是通过extends关键字来实现的。在定义类时使用extends关键字指明新定义类的父类,新定义的类称为指定父类的子类,这样就在两个类之间建立了继承关系。extends关键词应用的格式如下:【例3-9】继承测试,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,程序运行效果如图3-10所示。2.属性的继承父类的属性(包括所有成员变量和方法)都将被子类所继承,但被继承并不等于就一定能被访问。在Java中,只有非私有型(public型、或缺省型)的属性(变量和方法)能被同包子类所继承并直接访问,如例4-9而对于父类中私有型(private型)的属性,子类将无权直接访问。【例3-10】私有属性继承测试1。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-11所示此例不能正常通过编译,原因是在子类SubClass的fn3()里越权访问l父类中的私有变量d。注意,对于任何类的private型变量,对外界而言它是隐藏的,它的访问范围仅限于其所属类的方法内部,如此例中SuperClass类的私有变量d,它可在该类的方法fn4()中被访问。那么,父类中的私有属性究竟如何被子类访问呢?可以通过子类继承一个父类的公有方法去访问该父类的私有成员变量。【例3-11】私有属性继承测试2。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-12所示。,上一页,下一页,返回,3.3项目支撑知识,3.子类的构造方法Java中的构造方法一般在new关键字定义新对象的时候由系统自动调用,而当定义子类对象的时候,系统除了执行子类本身的构造方法,在默认情况下还会自动地执行父类的构造方法。【例3-12】子类构造方法测试(1)。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-13所示。,上一页,下一页,返回,3.3项目支撑知识,本例不能正确通过Java编译,出现如上所示错误,原因在于执行Square的构造语句时出错。由于该Square类是Rectangle类的子类,Java规定子类构造方法在真正被执行之前,首先需回溯执行父类的构造方法,系统在执行:Squaresquare=newSquare(10);时首先执行父类Rectangle类的构造方法,默认情况下是执行父类的空构造方法,而此例Rectangle类中已经定义r显式的Rectangle(inta,inth型的构造方法,所以系统将不再为Rectangle类生成默认的空构造方法,这样程序运行时就找不到匹配的父类构造方法了,解决的方法有多种。方法一:为父类添加空构造方法,需修改的代码如下。,上一页,下一页,返回,3.3项目支撑知识,方法二:在子类的构造方法中明确指明需执行的父类构造方法的类型,修改的代码如下。,上一页,下一页,返回,3.3项目支撑知识,不管使用何种方法,程序都能正确运行,得到一致的结果,如图3-14所示。,上一页,下一页,返回,3.3项目支撑知识,二、类的多态多态的存在是类之间继承关系的必然结果,正是因为继承关系,使得两个类之间有了一种比较亲密的关系:父与子的关系。多态的概念,通俗讲,就是系统自动识别当前对象变量的类型(子类或父类),并访问其相应的属性或方法。在Java语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法覆盖实现的动态多态性(运行时多态)。编译时多态在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。,上一页,下一页,返回,3.3项目支撑知识,重载,是指同一个类中允许存在多个同名方法,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)的现象,重载现在可以发生在任何类中。【例3-13】编译时多态测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-15所示。2.运行时多态由于子类继承了父类所有的属性,所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用子类的方法。覆盖,是指子类中重新定义父类的同名方法的现象,如果一个类中存在着覆盖现象,则该类应为另一类的子类。覆盖方法的调用原则:Java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类覆盖了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未覆盖),则运行时系统调用父类的方法。,上一页,下一页,返回,3.3项目支撑知识,【例3-14】运行时多态测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-16所示。3.3.6项目开发背景知识6访问控制与修饰符一、Java访问控制符Java语言规定类中的成员变量或方法具有4种不同的访问控制符,对应于4种不同的访问权限。表3-3列出了这些访问控制符的作用范围。(1)private,上一页,下一页,返回,3.3项目支撑知识,类中被private关键词修饰的成员变量或方法,只能在这个类本身的方法内部被访问。如果一个类的构造方法声明为private,则该类通常为另一个类的内部类。(2)default类中不被任何访问控制符修饰的成员变量或方法属于缺省的(default)访问状态,可以被这个类本身和同一个包中的类所访问。(3)protected类中被protected关键词修饰的成员变量或方法,可以被这个类本身、它的子类(包括同一个包中以及不同包中的子类)和同一个包中的所有其他的类访问。,上一页,下一页,返回,3.3项目支撑知识,(4)public类中被public关键词修饰的成员,可以被所有的类访问。表3-3列出了这些访问控制符的作用范转。二、Java修饰符static修饰符(1)static型变量。static型变量,即静态型变量,全局型的静态变量通常用来描述属于类的变量,我们在前面已具体介绍过,可参见3.3.3节。(2)static型方法。,上一页,下一页,返回,3.3项目支撑知识,用static修饰符修饰的方法被称为静态方法,它是属于整个类的类方法。不用static修饰符限定的方法,是属于某个具体类对象的方法。static方法使用特点如下。static方法是属于整个类的,它在内存中的代码段将随着类的定义而分配和装载。而非static的方法是属于某个对象的方法,当这个对象创建时,在对象的内存中拥有这个方法的专用代码段。,上一页,下一页,返回,3.3项目支撑知识,引用静态方法时,可以使用对象名做引用者,也可以使用类名做引用者;static方法只能访问static数据成员,不能访问非static数据成员,但非static方法可以访问static数据成员。static方法只能访问static方法,不能访问非static方法,但非static方法可以访问static方法。static方法不能被覆盖,也就是说,子类中不能有与父类中的static方法具有相同名、相同参数的方法。,上一页,下一页,返回,3.3项目支撑知识,main方法是静态方法。在Java的每个Application程序中,都必须有且只能有一个mian方法,它是Application程序运行的入口点。【例3-15】StaticMethodTest.Java类方法测试。,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-17所示。,上一页,下一页,返回,3.3项目支撑知识,类似于类变量的调用,静态方法(类方法)也可以使用对象名来调用,但我们建议使用类名来调用静态方法,这样更能体现静态方法属于类的特性。如此例中,可以编写如下代码:程序运行的效果不变。此外,static型方法声明及使用的时候,有诸多地方容易出错,需引起注意如下所示。【例3-16】,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,本例程序不能通过编译,错误原因如注释所示。.static型语句块。Java语法规定类中不属于任何方法的代码可以放在一个由static修饰的语句块中,这是完全有效的,这样的语句块代码被称之为静态块代码。静态块代码中若要处理类的成员变量或方法那都只能是静态型的。当类被装载时,静态块代码只被执行一次。若类中含有不同的静态块代码,那么它们的执行顺序按照它们在类中出现的顺序被执行。【例3-17】StaticBlockTest.Java静态块语句测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-18所示。2.final修饰符.final型变量如果变量被标记为final,其结果是使它成为常量。想改变final变量的值会导致一个编译错误。下面是一个正确定义final变量的例子:,上一页,下一页,返回,3.3项目支撑知识,如果将引用类型(即任何类的类型)的变量标记为final,那么该变量不能指向任何其他对象。但可以改变对象的内容,因为只有引用本身是final。【例3-18】FinalVarTest.Java最终变量测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-19所示。,上一页,下一页,返回,3.3项目支撑知识,.final型方法。在面向对象的程序设计中,子类可以利用重载机制修改从父类那里继承来的某些数据成员及成员方法,这给程序设计带来方便的同时,也给系统的安全性带来了威胁。为此,Java语言提供了final修饰符来保证系统的安全。用final修饰符修饰的方法称为最终方法,如果类的某个方法被final修饰符所限定,则该类的子类就不能覆盖父类的方法,即不能再重新定义与此方法同名的自己的方法,而仅能使用从父类继承来的方法。可见,使用final修饰方法,就是为了给方法“上锁”,防止任何继承类修改此方法,保证厂程序的安全性和正确性。【例3-19】最终方法测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,本例程序的编译结果如图3-20所示。,上一页,下一页,返回,3.3项目支撑知识,本例程序的编译不能正常通过,错误原因如代码中的注释所示。从运行的结果看,父类中被标记为static的方法在子类中也不能被正常的覆盖,这是由于类中的static型方法会自动地被系统定为final型,因此它也不能被覆盖。.final型类。final修饰符也可用于修饰类,而当用final修饰符修饰类时,所有包含在final类中的方法,都自动成为final方法。final类本身是不允许被任何类继承的。【例3-20】final类测试。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】本例程序不能通过正常编译,其编译出错信息如图3-21所示。3.3.7项目开发背景知识7抽象类、接口和包在日常生活中,有许多概念是抽象的,这种抽象概念的类没有实例(实物)对照。比如水果是抽象类,它在现实生活中没有具体的实物与之对照。在日常的生活中只有苹果、香蕉、橘子等,它们都是水果的子类,但不是水果的实例。因此,在Java中经常需要定义一个给出抽象结构、但不给出每个成员函数的完整实现的类,即抽象类。抽象类是指不能直接实例化对象的类。,上一页,下一页,返回,3.3项目支撑知识,如果一个抽象类被说明了,则这个类中将包括一个或几个抽象方法。所谓抽象方法是指该方法只有方法说明却没有方法体,即没有具体的代码。定义抽象类的目的就是为了给子类提供一种共同的行为描述,为所有的子类定义一个统一的接口。一、抽象类Java语言中,用abstract关键字来修饰一个类时,这个类叫做抽象类,用abstract关键字来修饰一个方法时,这个方法叫做抽象方法。格式如下:,上一页,下一页,返回,3.3项目支撑知识,抽象类必须被继承,抽象方法必须被重写。抽象方法只需声明,无需实现;抽象类不一定要包含抽象方法。若类中包含了抽象方法,则该类必须被定义为抽象类。【例3-21】源程序Abstract.Java,一个带有抽象成员函数的类。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-22所示。【程序分析】第17句:定义抽象类A;第3句在A类中声明callme()为抽象方法。第9句定义A的子类。第11句重载calltme的方法;第20句在Abstract类中生成B类的一个实例,并将它的引用返回值给a。二、接口Java语言不支持多继承性,即一个子类只能有一个父类,但有时子类需要继承多个父类的特性,因此,引人了接口。,上一页,下一页,返回,3.3项目支撑知识,在日常生活中,一个电源插座可以接电视机、电脑、电饭煲等家电。对于插座来说,这些电器都是可插入的构件,之所以可插入,因为它们都具有与插座相匹酉己的插头。一个插座无论是两相的还是三相的,也无论生产插座的厂家是哪里的,都会执行相同的规范,因此当用户购买到插座以后都可以使用。在这里我们关心的是制造插座的规范,并不关心这个插座是用来接电视机或电饭煲;作为生产插座的厂家关心的也只是制造这个插座过程中所执行的规范,他们只要按照规范生产出来的插座,用户就一定可以正常使用。,上一页,下一页,返回,3.3项目支撑知识,不同的厂家生产出来的插座都可以使用。这是因为不同的生产厂家都执行厂生产插座相同的规范,这个规范是由相关部门制定的,这个部门只是制定厂规范,但并不管生产是如何进行的。接口本身就类似于上例中的制定插座规范的部门,在接口中声明的行为规范(体现在编程语言中就是方法的声明,只有声明而没有方法体),也就是生产厂家所执行的生产规范,生产厂家对应的就是类,也就是说接口是通过类来实现的。这正如生产插座的厂家要执行工业部关于插座的生产规范,类也要执行接口中定义的行为规范,也就是方法。,上一页,下一页,返回,3.3项目支撑知识,Java接口(Interface),是一些抽象方法和常量的集合。接口只有方法的特征,而没有实现,这些功能的真正实现是在继承这个接口的各个类中完成的。也就是说,接口定义仅仅是实现某一特定功能的一组功能的对外接口和规范,并没有真正实现这些功能。1.接口的定义编写一个接口时,需要使用关键字interface而不是class,接口定义的一般形式为:,上一页,下一页,返回,3.3项目支撑知识,接口体(1)接口修饰符。接口修饰符为接口访问权限,有public和缺省两种状态。1)public状态。用public指明任意类均可以使用这个接口。2)缺省状态。在缺省情况下,只有与该接口定义在同一包中的类才可以访问这个接口,而其他包中的类无权访问该接口。,上一页,下一页,返回,3.3项目支撑知识,(2)父类接口列表一个接口可以继承其他接口,可通过关键词extends来实现,其语法与类的继承相同。被继承的类接口称为父类接口,当有多个父类接口时,用逗号“,”分隔。(3)接口体。接口体中包括接口中所需要说明的常量和抽象方法。由于接口体中只有常量,所以接口体中的变量只能定义为static和final型,在类实现接口时不能被修改,而且必须用常量初始化。接口体中的方法说明与类体中的方法说明形式一样,由于接口体中的方法为抽象方法,所以没有方法体。接口体中方法多被说明成public型。,上一页,下一页,返回,3.3项目支撑知识,2.接口的实现当一个类要为一个接口实现其具体功能时,要使用关键字implements。一个类可以同时实现多个接口。在类体中可以使用接口中定义的常量,由于接口中的方法为抽象方法,所以必须在类体中加入要实现接口方法的代码,如果一个接口是从别的一个或多个父接口中继承而来,则在类体中必须加人实现该接口及其父接口中所有方法的代码。在实现一个接口时,类中对方法的定义要和接口中的相应的方法的定义相匹配,其方法名、方法的返回值类型、方法的访问权限和参数的数目与类型信息要一致。【例322】源程序名interfacetest.Java,是接口的例子。,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,上一页,下一页,返回,3.3项目支撑知识,【运行结果】如图3-23所示。【程序分析】第15句:定义了接口1,其中定义了常量PI和求面积的抽象方法。第710句:定义了接口2,其中定义了求体积的抽象方法。第1344句:主程序中用implements引入了两个接口;在类体中实现了两个抽象方法。注意:接口是一种特殊的类,但接口与类存在着本质的区别,类有它的成员变量和成员方法,而接口却只有常量和抽象方法,一个类可以有多个接口。Java语言通过接口使得处于不同类甚至互不相关的类可以具有相同的行为。,上一页,下一页,返回,3.3项目支撑知识,三、包“包”的机制是Java中特有的,也是Java中最基础的知识。其引人的主要原因是Java本身跨平台特性的需求。因为Java

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论