JAVAObject入门

上传人:博****1 文档编号:590079736 上传时间:2024-09-12 格式:PPT 页数:86 大小:271.50KB
返回 下载 相关 举报
JAVAObject入门_第1页
第1页 / 共86页
JAVAObject入门_第2页
第2页 / 共86页
JAVAObject入门_第3页
第3页 / 共86页
JAVAObject入门_第4页
第4页 / 共86页
JAVAObject入门_第5页
第5页 / 共86页
点击查看更多>>
资源描述

《JAVAObject入门》由会员分享,可在线阅读,更多相关《JAVAObject入门(86页珍藏版)》请在金锄头文库上搜索。

1、1 Object 入门入门面向对象程序设计面向对象程序设计JavaJava0一、一、Object 介绍介绍u抽象抽象u对象的接口对象的接口u实现方案的隐藏实现方案的隐藏u方案的重复使用方案的重复使用u继承:重新使用继承:重新使用接口接口u多形对象的互换多形对象的互换使用使用u对象的创建和存在时对象的创建和存在时间间u违例控制:解决错误违例控制:解决错误u多线程多线程u永久性永久性uJava和因特网和因特网u分析和设计分析和设计uJava还是还是C+?11.抽象抽象 所有编程语言的最终目的都是提供一种所有编程语言的最终目的都是提供一种“抽象抽象”方法。方法。一种较有争议的说法是:一种较有争议的说

2、法是:解决问题的复杂程度直接取决于解决问题的复杂程度直接取决于抽象的种类及质量抽象的种类及质量。这儿的。这儿的“种类种类”是指准备对什么进行是指准备对什么进行“抽象抽象”?汇编语言是对基础机器的少量抽象汇编语言是对基础机器的少量抽象。后来的后来的许许多多“命令式命令式”语言语言(如(如FORTRAN,BASIC和和C)是对汇是对汇编语言的一种抽象编语言的一种抽象。与汇编语言相比,这些语言已有了长。与汇编语言相比,这些语言已有了长足的进步,但它们的足的进步,但它们的抽象原理抽象原理依然要求我们依然要求我们着重考虑计算着重考虑计算机的结构,而非考虑问题本身的结构机的结构,而非考虑问题本身的结构。在

3、。在机器模型机器模型(位于(位于“方案空间方案空间”)与实际解决的)与实际解决的问题模型问题模型(位于(位于“问题空间问题空间”)之间,)之间,程序员必须建立起一种联系程序员必须建立起一种联系。这个过程要求人。这个过程要求人们付出较大的精力,而且由于它脱离了编程语言本身的范们付出较大的精力,而且由于它脱离了编程语言本身的范围,造成程序代码很难编写,而且要花较大的代价进行维围,造成程序代码很难编写,而且要花较大的代价进行维护。由此造成的护。由此造成的副作用便是一门完善的副作用便是一门完善的“编程方法编程方法”学科学科。 21.抽象抽象 为机器建模的为机器建模的另一个方法另一个方法是为要解决的问题

4、制是为要解决的问题制作模型。对一些早期语言来说,如作模型。对一些早期语言来说,如LISP和和APL,它们的做法它们的做法是是“从不同的角度观察世界从不同的角度观察世界”“所所有问题都归纳为列表有问题都归纳为列表”或或“所有问题都归纳为算法所有问题都归纳为算法”。PROLOG则将所有问题都归纳为决策链则将所有问题都归纳为决策链。对。对于这些语言,我们认为它们一部分是面向基于于这些语言,我们认为它们一部分是面向基于“强强制制”的编程,另一部分则是专为处理图形符号设计的编程,另一部分则是专为处理图形符号设计的。每种方法都有自己特殊的用途,适合解决某一的。每种方法都有自己特殊的用途,适合解决某一类的问

5、题。但类的问题。但只要超出了它们力所能及的范围,就只要超出了它们力所能及的范围,就会显得非常笨拙会显得非常笨拙。 31.抽象抽象 面向对象的程序设计在此基础上则跨出了一大步,程面向对象的程序设计在此基础上则跨出了一大步,程序员可利用一些工具表达问题空间内的元素。由于这种表序员可利用一些工具表达问题空间内的元素。由于这种表达非常普遍,所以不必受限于特定类型的问题。我们达非常普遍,所以不必受限于特定类型的问题。我们将问将问题空间中的元素以及它们在方案空间的表示物称作题空间中的元素以及它们在方案空间的表示物称作“对象对象”(Object)。当然,还有一些在问题空间没有对应体的。当然,还有一些在问题空

6、间没有对应体的其他对象。通过添加新的对象类型,程序可进行灵活的调其他对象。通过添加新的对象类型,程序可进行灵活的调整,以便与特定的问题配合。所以在阅读方案的描述代码整,以便与特定的问题配合。所以在阅读方案的描述代码时,会读到对问题进行表达的话语。与我们以前见过的相时,会读到对问题进行表达的话语。与我们以前见过的相比,这无疑是一种更加灵活、更加强大的语言抽象方法。比,这无疑是一种更加灵活、更加强大的语言抽象方法。总之,总之,OOP允许我们根据问题来描述问题,而不是根据方允许我们根据问题来描述问题,而不是根据方案案。然而,仍有一个联系途径回到计算机。每个对象都类。然而,仍有一个联系途径回到计算机。

7、每个对象都类似一台小计算机;它们有自己的状态,而且可要求它们进似一台小计算机;它们有自己的状态,而且可要求它们进行特定的操作。与现实世界的行特定的操作。与现实世界的“对象对象”或者或者“物体物体”相比,相比,编程编程“对象对象”与它们也存在共通的地方:它们都有自己的与它们也存在共通的地方:它们都有自己的特征和行为。特征和行为。 41.抽象抽象 Alan Kay总结了总结了Smalltalk的五大基本特征。这是第的五大基本特征。这是第一种成功的面向对象程序设计语言,也是一种成功的面向对象程序设计语言,也是Java的基的基础语言。通过这些特征,我们可理解础语言。通过这些特征,我们可理解“纯粹纯粹”

8、的面的面向对象程序设计方法是什么样的:向对象程序设计方法是什么样的:u所有东西都是对象所有东西都是对象 u程序是一大堆对象的组合;通过消息传递,各对程序是一大堆对象的组合;通过消息传递,各对象知道自己该做些什么象知道自己该做些什么 u每个对象都有自己的存储空间,可容纳其他对象每个对象都有自己的存储空间,可容纳其他对象 u每个对象都有一种类型每个对象都有一种类型 u同一类所有对象都能接收相同的消息同一类所有对象都能接收相同的消息 52.对象的接口对象的接口 亚里士多德或许是认真研究亚里士多德或许是认真研究“类型类型”概念的第概念的第一人,他曾谈及一人,他曾谈及“鱼类和鸟类鱼类和鸟类”的问题。在的

9、问题。在世界首世界首例面向对象语言例面向对象语言Simula-67中,第一次用到了这样中,第一次用到了这样的一个概念:的一个概念:所有对象所有对象尽管各有特色尽管各有特色都属于某一系都属于某一系列对象的一部分,这些对象具有通用的特征和行为列对象的一部分,这些对象具有通用的特征和行为。在在Simula-67中,首次用到了中,首次用到了class这个关键字,它这个关键字,它为程序引入了一个全新的类型。为程序引入了一个全新的类型。62.对象的接口对象的接口 Simula是一个很好的例子。这里有象是一个很好的例子。这里有象“银行出银行出纳员纳员”这样的经典问题。这样的经典问题。这里,我们有一系列出纳员

10、、客户、帐号以及这里,我们有一系列出纳员、客户、帐号以及交易等。每类成员(元素)都具有一些交易等。每类成员(元素)都具有一些通用的特征通用的特征:每个帐号都有一定的余额;每名出纳都能接收客户每个帐号都有一定的余额;每名出纳都能接收客户的存款;等等。与此同时,每个成员都有自己的状的存款;等等。与此同时,每个成员都有自己的状态;每个帐号都有不同的余额;每名出纳都有一个态;每个帐号都有不同的余额;每名出纳都有一个名字。所以在计算机程序中,能用独一无二的实体名字。所以在计算机程序中,能用独一无二的实体分别表示出纳员、客户、帐号以及交易。分别表示出纳员、客户、帐号以及交易。这个实体这个实体便是便是“对象

11、对象”,而且每个对象都隶属一个特定的,而且每个对象都隶属一个特定的“类类”,那个类具有自己的通用特征与行为,那个类具有自己的通用特征与行为。72.对象的接口对象的接口 因此,在面向对象的程序设计中,尽管我们真因此,在面向对象的程序设计中,尽管我们真正要做的是新建各种各样的数据正要做的是新建各种各样的数据“类型类型”(Type),但几乎所有面向对象的程序设计语),但几乎所有面向对象的程序设计语言都采用了言都采用了“class”关键字。当您看到关键字。当您看到“type”这个字的时候,请同时想到这个字的时候,请同时想到“class”;反之亦然。;反之亦然。建好一个类后,可根据情况生成许多对象建好一

12、个类后,可根据情况生成许多对象。随。随后,可将那些对象作为要解决问题中存在的元素进后,可将那些对象作为要解决问题中存在的元素进行处理。事实上,当我们进行面向对象的程序设计行处理。事实上,当我们进行面向对象的程序设计时,面临的时,面临的最大一项挑战性就是最大一项挑战性就是:如何在:如何在“问题空问题空间间”(问题实际存在的地方)的元素与(问题实际存在的地方)的元素与“方案空间方案空间”(对实际问题进行建模的地方,如计算机)的元(对实际问题进行建模的地方,如计算机)的元素之间素之间建立理想的建立理想的“一对一一对一”对应或映射关系对应或映射关系。82.对象的接口对象的接口 如何利用对象完成真正有用

13、的工作呢?如何利用对象完成真正有用的工作呢?必须有必须有一种办法能向对象发出请求,令其做一些实际的事一种办法能向对象发出请求,令其做一些实际的事情,情,比如完成一次交易、在屏幕上画一些东西或者比如完成一次交易、在屏幕上画一些东西或者打开一个开关等等。每个对象仅能接受特定的请求。打开一个开关等等。每个对象仅能接受特定的请求。我们向对象发出的请求是通过它的我们向对象发出的请求是通过它的“接口接口”(Interface)定义的,)定义的,对象的对象的“类型类型”或或“类类”则规定了它的接口形式则规定了它的接口形式。“类型类型”与与“接口接口”的等价或对应关系是面向的等价或对应关系是面向对象程序设计的

14、基础对象程序设计的基础。92.对象的接口对象的接口 Light lt = Light lt = newnew Light(); Light();lt.on();lt.on();103.实现的隐藏实现的隐藏 从根本上说,大致有两方面的人员涉足面向对从根本上说,大致有两方面的人员涉足面向对象的编程:象的编程:“类创建者类创建者”(创建新数据类型的人)(创建新数据类型的人)以及以及“客户程序员客户程序员” 。对。对客户程序员客户程序员来讲,最主来讲,最主要的要的目标目标就是就是收集一个充斥着各种类的编程收集一个充斥着各种类的编程“工具工具箱箱”,以便快速开发符合自己要求的应用,以便快速开发符合自己要

15、求的应用。而对。而对类类创建者创建者来说,他们的来说,他们的目标目标则是则是从头构建一个类,只从头构建一个类,只向客户程序员开放有必要开放的东西(接口),其向客户程序员开放有必要开放的东西(接口),其他所有细节都隐藏起来他所有细节都隐藏起来。为什么要这样做?隐藏之后,客户程序员就不为什么要这样做?隐藏之后,客户程序员就不能接触和改变那些细节,所以原创者不用担心自己能接触和改变那些细节,所以原创者不用担心自己的作品会受到非法修改,可确保它们不会对其他人的作品会受到非法修改,可确保它们不会对其他人造成影响。造成影响。113.实现的隐藏实现的隐藏 “接口接口”(Interface)规定了可对一个特定

16、的)规定了可对一个特定的对象发出哪些请求。然而,必须在某个地方存在着对象发出哪些请求。然而,必须在某个地方存在着一些代码,以便满足这些请求。这些代码与那些隐一些代码,以便满足这些请求。这些代码与那些隐藏起来的数据便叫作藏起来的数据便叫作“隐藏的实现隐藏的实现”。站在过程化。站在过程化程序编写(程序编写(Procedural Programming)的角度,整)的角度,整个问题并不显得复杂。一种类型含有与每种可能的个问题并不显得复杂。一种类型含有与每种可能的请求关联起来的函数。一旦向对象发出一个特定的请求关联起来的函数。一旦向对象发出一个特定的请求,就会调用那个函数。我们通常将这个过程总请求,就

17、会调用那个函数。我们通常将这个过程总结为向对象结为向对象“发送一条消息发送一条消息”(提出一个请求)。(提出一个请求)。对象的职责就是决定如何对这条消息作出反应对象的职责就是决定如何对这条消息作出反应(执(执行相应的代码)。行相应的代码)。123.实现的隐藏实现的隐藏 对于任何关系,重要一点是让牵连到的所有成对于任何关系,重要一点是让牵连到的所有成员都遵守相同的规则员都遵守相同的规则。创建一个库时,相当于同客。创建一个库时,相当于同客户程序员建立了一种关系。对方也是程序员,但他户程序员建立了一种关系。对方也是程序员,但他们的目标是组合出一个特定的应用(程序),或者们的目标是组合出一个特定的应用

18、(程序),或者用您的库构建一个更大的库。用您的库构建一个更大的库。若任何人都能使用一个类的所有成员,那么客若任何人都能使用一个类的所有成员,那么客户程序员可对那个类做任何事情,没有办法强制他户程序员可对那个类做任何事情,没有办法强制他们遵守任何约束。即便非常不愿客户程序员直接操们遵守任何约束。即便非常不愿客户程序员直接操作类内包含的一些成员,但倘若未进行访问控制,作类内包含的一些成员,但倘若未进行访问控制,就没有办法阻止这一情况的发生就没有办法阻止这一情况的发生所有东西都会所有东西都会暴露无遗。暴露无遗。133.实现的隐藏实现的隐藏 有两方面的原因促使我们控制对成员的访问有两方面的原因促使我们

19、控制对成员的访问。第一第一个原因是防止程序员接触他们不该接触的东西个原因是防止程序员接触他们不该接触的东西通常是通常是内部数据类型的设计思想。若只是为了解决特定的问题,内部数据类型的设计思想。若只是为了解决特定的问题,用户只需操作接口即可,毋需明白这些信息。我们向用户用户只需操作接口即可,毋需明白这些信息。我们向用户提供的实际是一种服务,因为他们很容易就可看出哪些对提供的实际是一种服务,因为他们很容易就可看出哪些对自己非常重要,以及哪些可忽略不计。自己非常重要,以及哪些可忽略不计。进行访问控制的第二个原因是允许库设计人员修改进行访问控制的第二个原因是允许库设计人员修改内部结构,不用担心它会对客

20、户程序员造成什么影响内部结构,不用担心它会对客户程序员造成什么影响。例。例如,我们最开始可能设计了一个形式简单的类,以便简化如,我们最开始可能设计了一个形式简单的类,以便简化开发。以后又决定进行改写,使其更快地运行。若接口与开发。以后又决定进行改写,使其更快地运行。若接口与实现方法早已隔离开,并分别受到保护,就可放心做到这实现方法早已隔离开,并分别受到保护,就可放心做到这一点,只要求用户重新链接一下即可。一点,只要求用户重新链接一下即可。143.实现的隐藏实现的隐藏 Java采用三个显式(明确)关键字以及一个隐式采用三个显式(明确)关键字以及一个隐式(暗示)关键字来设置类边界:(暗示)关键字来

21、设置类边界:public,private,protected以及暗示性的以及暗示性的friendly。若未明确指定其他关键。若未明确指定其他关键字,则默认为后者。这些关键字的使用和含义都是相当直字,则默认为后者。这些关键字的使用和含义都是相当直观的,它们决定了谁能使用后续的定义内容。观的,它们决定了谁能使用后续的定义内容。“public”(公共)意味着后续的定义任何人均可使用。(公共)意味着后续的定义任何人均可使用。而在另一方面,而在另一方面,“private”(私有)意味着除您自己、(私有)意味着除您自己、类型的创建者以及那个类型的内部函数成员,其他任何人类型的创建者以及那个类型的内部函数成

22、员,其他任何人都不能访问后续的定义信息。都不能访问后续的定义信息。private在您与客户程序员之在您与客户程序员之间竖起了一堵墙。若有人试图访问私有成员,就会得到一间竖起了一堵墙。若有人试图访问私有成员,就会得到一个编译期错误。个编译期错误。“friendly”(友好的)涉及(友好的)涉及“包装包装”或或“封装封装”(Package)的概念)的概念即即Java用来构建库的方用来构建库的方法。若某样东西是法。若某样东西是“友好的友好的”,意味着它只能在这个包装,意味着它只能在这个包装的范围内使用(所以这一访问级别有时也叫作的范围内使用(所以这一访问级别有时也叫作“包装访问包装访问”)。)。“p

23、rotected”(受保护的)与(受保护的)与“private”相似,相似,只是一个继承的类可访问受保护的成员,但不能访问私有只是一个继承的类可访问受保护的成员,但不能访问私有成员。继承的问题不久就要谈到。成员。继承的问题不久就要谈到。154.实现的重用实现的重用 u创建并测试好一个类后,它应(从理想的角度)代表一个创建并测试好一个类后,它应(从理想的角度)代表一个有用的代码单位。但并不象许多人希望的那样,这种重复有用的代码单位。但并不象许多人希望的那样,这种重复使用的能力并不容易实现;它要求较多的经验以及洞察力,使用的能力并不容易实现;它要求较多的经验以及洞察力,这样才能设计出一个好的方案,

24、才有可能重复使用。这样才能设计出一个好的方案,才有可能重复使用。 u许多人认为代码或设计方案的重复使用是面向对象的程序许多人认为代码或设计方案的重复使用是面向对象的程序设计提供的最伟大的一种杠杆。设计提供的最伟大的一种杠杆。164.实现的重用实现的重用为重复使用一个类,最简单的办法是仅直接使用那个为重复使用一个类,最简单的办法是仅直接使用那个类的对象。但同时也能将那个类的一个对象置入一个新类。类的对象。但同时也能将那个类的一个对象置入一个新类。把这叫作把这叫作“创建一个成员对象创建一个成员对象”。新类可由任意数量和类。新类可由任意数量和类型的其他对象构成。无论如何,只要新类达到了设计要求型的其

25、他对象构成。无论如何,只要新类达到了设计要求即可。这个概念叫作即可。这个概念叫作“组织组织”在现有类的基础上组织在现有类的基础上组织一个新类一个新类。有时,我们也将组织称作。有时,我们也将组织称作“包含包含”关系关系,比如,比如“一辆车包含了一个变速箱一辆车包含了一个变速箱”。174.实现的重用实现的重用对象的组织具有极大的灵活性。新类的对象的组织具有极大的灵活性。新类的“成员对象成员对象”通常设为通常设为“私有私有”(Private),使用这个类的客户程序员),使用这个类的客户程序员不能访问它们。这样一来,我们可在不干扰客户代码的前不能访问它们。这样一来,我们可在不干扰客户代码的前提下,从容

26、地修改那些成员。也可以在提下,从容地修改那些成员。也可以在“运行期运行期”更改成更改成员,这进一步增大了灵活性。后面要讲到的员,这进一步增大了灵活性。后面要讲到的“继承继承”并不并不具备这种灵活性,因为编译器必须对通过继承创建的类加具备这种灵活性,因为编译器必须对通过继承创建的类加以限制。以限制。由于继承的重要性,所以在面向对象的程序设计中,由于继承的重要性,所以在面向对象的程序设计中,它经常被重点强调。它经常被重点强调。作为新加入这一领域的程序员,或许作为新加入这一领域的程序员,或许早已先入为主地认为早已先入为主地认为“继承应当随处可见继承应当随处可见”。沿这种思路沿这种思路产生的设计将是非

27、常笨拙的,会大大增加程序的复杂程度产生的设计将是非常笨拙的,会大大增加程序的复杂程度。相反,新建类的时候,首先应考虑相反,新建类的时候,首先应考虑“组织组织”对象;这样做对象;这样做显得更加简单和灵活。利用对象的组织,我们的设计可保显得更加简单和灵活。利用对象的组织,我们的设计可保持清爽。一旦需要用到继承,就会明显意识到这一点。持清爽。一旦需要用到继承,就会明显意识到这一点。185.继承继承 :接口的重用:接口的重用就其本身来说,对象的概念可为我们带来极大的便利。就其本身来说,对象的概念可为我们带来极大的便利。它在概念上允许我们将各式各样数据和功能封装到一起。它在概念上允许我们将各式各样数据和

28、功能封装到一起。这样便可恰当表达这样便可恰当表达“问题空间问题空间”的概念,不用刻意遵照基的概念,不用刻意遵照基础机器的表达方式础机器的表达方式。在程序设计语言中,这些概念则反映。在程序设计语言中,这些概念则反映为具体的数据类型(使用为具体的数据类型(使用class关键字)。关键字)。我们费尽心思做出一种数据类型后,假如不得不又新我们费尽心思做出一种数据类型后,假如不得不又新建一种类型,令其实现大致相同的功能,那会是一件非常建一种类型,令其实现大致相同的功能,那会是一件非常令人灰心的事情。令人灰心的事情。但若能利用现成的数据类型,对其进行但若能利用现成的数据类型,对其进行“克隆克隆”,再根据情

29、况进行添加和修改,情况就显得理想,再根据情况进行添加和修改,情况就显得理想多了多了。“继承继承”正是针对这个目标而设计的。但继承并不正是针对这个目标而设计的。但继承并不完全等价于克隆完全等价于克隆。在继承过程中,若原始类(正式名称叫。在继承过程中,若原始类(正式名称叫作基础类、超类或父类)发生了变化,修改过的作基础类、超类或父类)发生了变化,修改过的“克隆克隆”类(正式名称叫作继承类或者子类)也会反映出这种变化。类(正式名称叫作继承类或者子类)也会反映出这种变化。在在Java语言中,继承是通过语言中,继承是通过extends关键字实现的。关键字实现的。195.继承继承 :接口的重用:接口的重用

30、使用继承时,相当于创建了一个新类。这个新类不仅使用继承时,相当于创建了一个新类。这个新类不仅包含了现有类型的所有成员(尽管包含了现有类型的所有成员(尽管private成员被隐藏起来,成员被隐藏起来,且不能访问),但更重要的是,它复制了基础类的接口且不能访问),但更重要的是,它复制了基础类的接口。也就是说,可向基础类的对象发送的所有消息亦可原样发也就是说,可向基础类的对象发送的所有消息亦可原样发给衍生类的对象。根据可以发送的消息,我们能知道类的给衍生类的对象。根据可以发送的消息,我们能知道类的类型。这意味着类型。这意味着衍生类具有与基础类相同的类型衍生类具有与基础类相同的类型!为真正!为真正理解

31、面向对象程序设计的含义,首先必须认识到这种类型理解面向对象程序设计的含义,首先必须认识到这种类型的等价关系。的等价关系。由于基础类和衍生类具有相同的接口,所以那个接口由于基础类和衍生类具有相同的接口,所以那个接口必须进行特殊的设计。也就是说,对象接收到一条特定的必须进行特殊的设计。也就是说,对象接收到一条特定的消息后,必须有一个消息后,必须有一个“方法方法”能够执行。若只是简单地继能够执行。若只是简单地继承一个类,并不做其他任何事情,来自基础类接口的方法承一个类,并不做其他任何事情,来自基础类接口的方法就会直接照搬到衍生类。这意味着衍生类的对象不仅有相就会直接照搬到衍生类。这意味着衍生类的对象

32、不仅有相同的类型,也有同样的行为,这一后果通常是我们不愿见同的类型,也有同样的行为,这一后果通常是我们不愿见到的。到的。205.继承继承 :接口的重用:接口的重用215.继承继承 :接口的重用:接口的重用225.继承继承 :接口的重用:接口的重用有两种做法可将新得的衍生类与原来的基础类有两种做法可将新得的衍生类与原来的基础类区分开区分开。第一种做法第一种做法十分简单:为衍生类添加新函十分简单:为衍生类添加新函数(功能)。这些新函数并非基础类接口的一部分。数(功能)。这些新函数并非基础类接口的一部分。进行这种处理时,一般都是意识到基础类不能满足进行这种处理时,一般都是意识到基础类不能满足我们的要

33、求,所以需要添加更多的函数。这是一种我们的要求,所以需要添加更多的函数。这是一种最简单、最基本的继承用法,大多数时候都可完美最简单、最基本的继承用法,大多数时候都可完美地解决我们的问题。然而,事先还是要仔细调查自地解决我们的问题。然而,事先还是要仔细调查自己的基础类是否真的需要这些额外的函数。己的基础类是否真的需要这些额外的函数。235.继承继承 :接口的重用:接口的重用245.继承继承 :接口的重用:接口的重用u改善基础类改善基础类 尽管尽管extends关键字暗示着我们要为接口关键字暗示着我们要为接口“扩展扩展”新功能,但实情并非肯定如此。为区分我们的新类,新功能,但实情并非肯定如此。为区

34、分我们的新类,第二个办法第二个办法是改变基础类一个现有函数的行为。我是改变基础类一个现有函数的行为。我们将其称作们将其称作“改善改善”那个函数。那个函数。为改善一个函数,只需为衍生类的函数建立一个新为改善一个函数,只需为衍生类的函数建立一个新定义即可。我们的目标是:定义即可。我们的目标是:“尽管使用的函数接口尽管使用的函数接口未变,但它的新版本具有不同的表现未变,但它的新版本具有不同的表现”。255.继承继承 :接口的重用:接口的重用265.继承继承 :接口的重用:接口的重用u等价与类似关系等价与类似关系 针对继承可能会产生这样的一个争论:针对继承可能会产生这样的一个争论:继承只能改善原基继承

35、只能改善原基础类的函数吗?础类的函数吗?若答案是肯定的,则衍生类型就是与基础若答案是肯定的,则衍生类型就是与基础类完全相同的类型,因为都拥有完全相同的接口。这样造类完全相同的类型,因为都拥有完全相同的接口。这样造成的结果就是:我们完全能够将衍生类的一个对象换成基成的结果就是:我们完全能够将衍生类的一个对象换成基础类的一个对象!可将其想象成一种础类的一个对象!可将其想象成一种“纯替换纯替换”。在某种。在某种意义上,这是进行继承的一种理想方式。此时,我们通常意义上,这是进行继承的一种理想方式。此时,我们通常认为基础类和衍生类之间存在一种认为基础类和衍生类之间存在一种“等价等价”关系关系因为因为我们

36、可以理直气壮地说:我们可以理直气壮地说:“圆就是一种几何形状圆就是一种几何形状”。为了。为了对继承进行测试,一个办法就是看看自己是否能把它们套对继承进行测试,一个办法就是看看自己是否能把它们套入这种入这种“等价等价”关系中,看看是否有意义。关系中,看看是否有意义。275.继承继承 :接口的重用:接口的重用但在许多时候,我们必须为衍生类型加入新的接口元但在许多时候,我们必须为衍生类型加入新的接口元素素。所以不仅扩展了接口,也创建了一种新类型。这种新。所以不仅扩展了接口,也创建了一种新类型。这种新类型仍可替换成基础类型,但这种替换并不是完美的,因类型仍可替换成基础类型,但这种替换并不是完美的,因为

37、不可在基础类里访问新函数。我们将其称作为不可在基础类里访问新函数。我们将其称作“类似类似”关关系;新类型拥有旧类型的接口,但也包含了其他函数,所系;新类型拥有旧类型的接口,但也包含了其他函数,所以不能说它们是完全等价的。以不能说它们是完全等价的。举个例子举个例子来说,让我们考虑来说,让我们考虑一下一下制冷机制冷机的情况。假定我们的房间连好了用于制冷的各的情况。假定我们的房间连好了用于制冷的各种控制器;也就是说,我们已拥有必要的种控制器;也就是说,我们已拥有必要的“接口接口”来控制来控制制冷。现在假设机器出了故障,我们把它换成一台新型的制冷。现在假设机器出了故障,我们把它换成一台新型的冷、热两用

38、空调,冬天和夏天均可使用。冷、热空调冷、热两用空调,冬天和夏天均可使用。冷、热空调“类类似似”制冷机,但能做更多的事情。由于我们的房间只安装制冷机,但能做更多的事情。由于我们的房间只安装了控制制冷的设备,所以它们只限于同新机器的制冷部分了控制制冷的设备,所以它们只限于同新机器的制冷部分打交道。新机器的接口已得到了扩展,但现有的系统并不打交道。新机器的接口已得到了扩展,但现有的系统并不知道除原始接口以外的任何东西。知道除原始接口以外的任何东西。285.继承继承 :接口的重用:接口的重用295.继承继承 :接口的重用:接口的重用认识了等价与类似的区别后,再进行替换时认识了等价与类似的区别后,再进行

39、替换时就会有把握得多。尽管大多数时候就会有把握得多。尽管大多数时候“纯替换纯替换”已经已经足够,但您会发现在某些情况下,仍然有明显的理足够,但您会发现在某些情况下,仍然有明显的理由需要在衍生类的基础上增添新功能。通过前面对由需要在衍生类的基础上增添新功能。通过前面对这两种情况的讨论,相信大家已心中有数该如何做。这两种情况的讨论,相信大家已心中有数该如何做。306.多形性(多形性(polymorphism )通常,继承最终会以创建一系列类收场,所有通常,继承最终会以创建一系列类收场,所有类都建立在统一的接口基础上。类都建立在统一的接口基础上。对这样的一系列类,我们要进行的一项重要处对这样的一系列

40、类,我们要进行的一项重要处理就是将衍生类的对象当作基础类的一个对象对待理就是将衍生类的对象当作基础类的一个对象对待。这一点是非常重要的,因为它意味着我们只需编写这一点是非常重要的,因为它意味着我们只需编写单一的代码,令其忽略类型的特定细节,只与基础单一的代码,令其忽略类型的特定细节,只与基础类打交道。这样一来,那些代码就可与类型信息分类打交道。这样一来,那些代码就可与类型信息分开。所以更易编写,也更易理解。此外,若通过继开。所以更易编写,也更易理解。此外,若通过继承增添了一种新类型,如承增添了一种新类型,如“三角形三角形”,那么我们为,那么我们为“几何形状几何形状”新类型编写的代码会象在旧类型

41、里一新类型编写的代码会象在旧类型里一样良好地工作。所以说程序具备了样良好地工作。所以说程序具备了“扩展能力扩展能力”,具有具有“扩展性扩展性”。316.多形性(多形性(polymorphism )326.多形性(多形性(polymorphism )336.多形性(多形性(polymorphism )void doStuff(Shape s) s.erase(); / . draw(); Circle c = new Circle();Triangle t = new Triangle(); Square s = new Square(); doStuff(c); doStuff(t); doS

42、tuff(s); 346.多形性(多形性(polymorphism )在面向对象的程序里,通常都要用到在面向对象的程序里,通常都要用到上溯造型技术上溯造型技术。这是避免去调查准确类型的一个好办法。请看看这是避免去调查准确类型的一个好办法。请看看doStuff()里的代码:里的代码:s.erase();/ .s.draw();注意它并未这样表达:注意它并未这样表达:“如果你是一个如果你是一个Circle,就这,就这样做;如果你是一个样做;如果你是一个Square,就那样做;等等,就那样做;等等”。若那样。若那样编写代码,就需检查一个编写代码,就需检查一个Shape所有可能的类型,如圆、所有可能的

43、类型,如圆、矩形等等。这显然是非常麻烦的,而且每次添加了一种新矩形等等。这显然是非常麻烦的,而且每次添加了一种新的的Shape类型后,都要相应地进行修改。在这儿,我们只类型后,都要相应地进行修改。在这儿,我们只需说:需说:“你是一种几何形状,我知道你能将自己删掉,即你是一种几何形状,我知道你能将自己删掉,即erase();请自己采取那个行动,并自己去控制所有的细节吧。;请自己采取那个行动,并自己去控制所有的细节吧。”356.多形性(多形性(polymorphism )u动态绑定动态绑定 在在doStuff()的代码里,最让人吃惊的是尽管我们没作出任的代码里,最让人吃惊的是尽管我们没作出任何特殊

44、指示,采取的操作也是完全正确和恰当的。我们知何特殊指示,采取的操作也是完全正确和恰当的。我们知道,为道,为Circle调用调用draw()时执行的代码与为一个时执行的代码与为一个Square或或Line调用调用draw()时执行的代码是不同的。但在将时执行的代码是不同的。但在将draw()消消息发给一个匿名息发给一个匿名Shape时,根据时,根据Shape句柄当时连接的实句柄当时连接的实际类型,会相应地采取正确的操作。这当然令人惊讶,因际类型,会相应地采取正确的操作。这当然令人惊讶,因为为当当Java编译器为编译器为doStuff()编译代码时,它并不知道自己编译代码时,它并不知道自己要操作的

45、准确类型是什么要操作的准确类型是什么。尽管我们确实可以保证最终会。尽管我们确实可以保证最终会为为Shape调用调用erase(),为,为Shape调用调用draw(),但并不能保证,但并不能保证为特定的为特定的Circle,Square或者或者Line调用什么。调用什么。然而最后采然而最后采取的操作同样是正确的,这是怎么做到的呢?取的操作同样是正确的,这是怎么做到的呢?366.多形性(多形性(polymorphism )将一条消息发给对象时,如果并不知道对方的具体类型是将一条消息发给对象时,如果并不知道对方的具体类型是什么,但采取的行动同样是正确的,这种情况就叫作什么,但采取的行动同样是正确的

46、,这种情况就叫作“多多形性形性”(Polymorphism)。对面向对象的程序设计语言)。对面向对象的程序设计语言来说,它们用以实现多形性的方法叫作来说,它们用以实现多形性的方法叫作“动态绑定动态绑定”。编编译器和运行期系统会负责对所有细节的控制译器和运行期系统会负责对所有细节的控制;我们只需知;我们只需知道会发生什么事情,而且更重要的是,如何利用它帮助自道会发生什么事情,而且更重要的是,如何利用它帮助自己设计程序己设计程序。有些语言要求我们用一个特殊的关键字来允许动态绑定。有些语言要求我们用一个特殊的关键字来允许动态绑定。在在C+中,这个关键字是中,这个关键字是virtual。在。在Java

47、中,我们则完全中,我们则完全不必记住添加一个关键字,因为函数的动态绑定是自动进不必记住添加一个关键字,因为函数的动态绑定是自动进行的。所以在将一条消息发给对象时,我们完全可以肯定行的。所以在将一条消息发给对象时,我们完全可以肯定对象会采取正确的行动,即使其中涉及上溯造型之类的处对象会采取正确的行动,即使其中涉及上溯造型之类的处理。理。376.多形性(多形性(polymorphism )u抽象的基础类和接口抽象的基础类和接口 设计程序时,我们经常都希望基础类只为自己的衍设计程序时,我们经常都希望基础类只为自己的衍生类提供一个接口。也就是说,我们不想其他任何生类提供一个接口。也就是说,我们不想其他

48、任何人实际创建基础类的一个对象,只对上溯造型成它,人实际创建基础类的一个对象,只对上溯造型成它,以便使用它们的接口。为达到这个目的,需要把那以便使用它们的接口。为达到这个目的,需要把那个类变成个类变成“抽象抽象”的的使用使用abstract关键字。若关键字。若有人试图创建抽象类的一个对象,编译器就会阻止有人试图创建抽象类的一个对象,编译器就会阻止他们。这种工具可有效强制实行一种特殊的设计。他们。这种工具可有效强制实行一种特殊的设计。386.多形性(多形性(polymorphism )亦可用亦可用abstract关键字描述一个尚未实现的方法关键字描述一个尚未实现的方法作为作为一个一个“根根”使用

49、,指出:使用,指出:“这是适用于从这个类继承的所这是适用于从这个类继承的所有类型的一个接口函数,但目前尚没有对它进行任何形式有类型的一个接口函数,但目前尚没有对它进行任何形式的实现。的实现。”抽象方法也许只能在一个抽象类里创建。继承抽象方法也许只能在一个抽象类里创建。继承了一个类后,那个方法就必须实现,否则继承的类也会变了一个类后,那个方法就必须实现,否则继承的类也会变成成“抽象抽象”类。通过创建一个抽象方法,我们可以将一个类。通过创建一个抽象方法,我们可以将一个方法置入接口中,不必再为那个方法提供可能毫无意义的方法置入接口中,不必再为那个方法提供可能毫无意义的主体代码。主体代码。interf

50、ace(接口)关键字将抽象类的概念更延伸了一步,(接口)关键字将抽象类的概念更延伸了一步,它完全禁止了所有的函数定义。它完全禁止了所有的函数定义。“接口接口”是一种相当有效是一种相当有效和常用的工具。另外如果自己愿意,亦可将多个接口都合和常用的工具。另外如果自己愿意,亦可将多个接口都合并到一起(不能从多个普通并到一起(不能从多个普通class或或abstract class中继承)。中继承)。397.对象的创建和存在时间对象的创建和存在时间 u如何控制对象的如何控制对象的“存在时间存在时间” ? u由谁负责清除?由谁负责清除? 407.对象的创建和存在时间对象的创建和存在时间 从技术角度说,从

51、技术角度说,OOP(面向对象程序设计)只是涉及(面向对象程序设计)只是涉及抽象的数据类型、继承以及多形性,但另一些问题也可能抽象的数据类型、继承以及多形性,但另一些问题也可能显得非常重要。下面将就这些问题进行探讨。显得非常重要。下面将就这些问题进行探讨。最重要的问题之一是对象的创建及破坏方式最重要的问题之一是对象的创建及破坏方式。对象需。对象需要的数据位于哪儿,要的数据位于哪儿,如何控制对象的如何控制对象的“存在时间存在时间”呢呢?针?针对这个问题,解决的方案是各异其趣的。对这个问题,解决的方案是各异其趣的。C+认为程序的认为程序的执行效率是最重要的一个问题,所以它允许程序员作出选执行效率是最

52、重要的一个问题,所以它允许程序员作出选择。为获得最快的运行速度,择。为获得最快的运行速度,存储以及存在时间可在编写存储以及存在时间可在编写程序时决定,只需将对象放置在堆栈(有时也叫作自动或程序时决定,只需将对象放置在堆栈(有时也叫作自动或定域变量)或者静态存储区域即可定域变量)或者静态存储区域即可。这样便为存储空间的。这样便为存储空间的分配和释放提供了一个优先级。某些情况下,这种优先级分配和释放提供了一个优先级。某些情况下,这种优先级的控制是非常有价值的。然而,我们同时也的控制是非常有价值的。然而,我们同时也牺牲了灵活性牺牲了灵活性,因为在编写程序时,必须知道对象的准确的数量、存在时因为在编写

53、程序时,必须知道对象的准确的数量、存在时间、以及类型间、以及类型。如果要解决的是一个较常规的问题,如计。如果要解决的是一个较常规的问题,如计算机辅助设计、仓储管理或者空中交通控制,这一方法就算机辅助设计、仓储管理或者空中交通控制,这一方法就显得太局限了。显得太局限了。417.对象的创建和存在时间对象的创建和存在时间 第二个方法是在一个内存池中动态创建对象,该内存第二个方法是在一个内存池中动态创建对象,该内存池亦叫池亦叫“堆堆”或者或者“内存堆内存堆”。若采用这种方式,除非进。若采用这种方式,除非进入入运行期运行期,否则根本不知道到底需要多少个对象,也不知否则根本不知道到底需要多少个对象,也不知

54、道它们的存在时间有多长,以及准确的类型是什么道它们的存在时间有多长,以及准确的类型是什么。这些。这些参数都在程序正式运行时才决定的。若需一个新对象,只参数都在程序正式运行时才决定的。若需一个新对象,只需在需要它的时候在内存堆里简单地创建它即可。由于存需在需要它的时候在内存堆里简单地创建它即可。由于存储空间的管理是运行期间动态进行的,所以在内存堆里分储空间的管理是运行期间动态进行的,所以在内存堆里分配存储空间的时间比在堆栈里创建的时间长得多(在堆栈配存储空间的时间比在堆栈里创建的时间长得多(在堆栈里创建存储空间一般只需要一个简单的指令,将堆栈指针里创建存储空间一般只需要一个简单的指令,将堆栈指针

55、向下或向下移动即可)。由于动态创建方法使对象本来就向下或向下移动即可)。由于动态创建方法使对象本来就倾向于复杂,所以查找存储空间以及释放它所需的额外开倾向于复杂,所以查找存储空间以及释放它所需的额外开销不会为对象的创建造成明显的影响。除此以外,更大的销不会为对象的创建造成明显的影响。除此以外,更大的灵活性对于常规编程问题的解决是至关重要的。灵活性对于常规编程问题的解决是至关重要的。427.对象的创建和存在时间对象的创建和存在时间 C+允许我们决定是在写程序时创建对象,还是在运允许我们决定是在写程序时创建对象,还是在运行期间创建,这种控制方法更加灵活行期间创建,这种控制方法更加灵活。大家或许认为

56、既然。大家或许认为既然它如此灵活,那么无论如何都应在内存堆里创建对象,而它如此灵活,那么无论如何都应在内存堆里创建对象,而不是在堆栈中创建。但还要考虑另外一个问题,不是在堆栈中创建。但还要考虑另外一个问题,亦即对象亦即对象的的“存在时间存在时间”或者或者“生存时间生存时间”(Lifetime)。若在堆。若在堆栈或者静态存储空间里创建一个对象,编译器会判断对象栈或者静态存储空间里创建一个对象,编译器会判断对象的持续时间有多长,到时会自动的持续时间有多长,到时会自动“破坏破坏”或者或者“清除清除”它。它。程序员可用程序员可用两种方法来破坏一个对象两种方法来破坏一个对象:用程序化的方式决用程序化的方

57、式决定何时破坏对象,或者利用由运行环境提供的一种定何时破坏对象,或者利用由运行环境提供的一种“垃圾垃圾收集器收集器”特性,自动寻找那些不再使用的对象,并将其清特性,自动寻找那些不再使用的对象,并将其清除除。当然,垃圾收集器显得方便得多,但要求所有应用程。当然,垃圾收集器显得方便得多,但要求所有应用程序都必须容忍垃圾收集器的存在,并能默许随垃圾收集带序都必须容忍垃圾收集器的存在,并能默许随垃圾收集带来的额外开销。但这并不符合来的额外开销。但这并不符合C+语言的设计宗旨,所以语言的设计宗旨,所以未能包括到未能包括到C+里。但里。但Java确实提供了一个垃圾收集器确实提供了一个垃圾收集器(Small

58、talk也有这样的设计;尽管也有这样的设计;尽管Delphi默认为没有垃圾默认为没有垃圾收集器,但可选择安装;而收集器,但可选择安装;而C+亦可使用一些由其他公司亦可使用一些由其他公司开发的垃圾收集产品)。开发的垃圾收集产品)。437.对象的创建和存在时间对象的创建和存在时间 每个对象都要求资源才能每个对象都要求资源才能“生存生存”,其中最令人注目,其中最令人注目的资源是内存。如果不再需要使用一个对象,就必须将其的资源是内存。如果不再需要使用一个对象,就必须将其清除,以便释放这些资源,以便其他对象使用。如果要解清除,以便释放这些资源,以便其他对象使用。如果要解决的是非常简单的问题,如何清除对象

59、这个问题并不显得决的是非常简单的问题,如何清除对象这个问题并不显得很突出:我们创建对象,在需要的时候调用它,然后将其很突出:我们创建对象,在需要的时候调用它,然后将其清除或者清除或者“破坏破坏”。但在另一方面,我们平时遇到的问题。但在另一方面,我们平时遇到的问题往往要比这复杂得多。往往要比这复杂得多。举个例子举个例子来说,假设我们要设计一套系统,用它来说,假设我们要设计一套系统,用它管理管理一个机场的空中交通一个机场的空中交通(同样的模型也可能适于管理一个仓(同样的模型也可能适于管理一个仓库的货柜、或者一套影带出租系统、或者宠物店的宠物房)库的货柜、或者一套影带出租系统、或者宠物店的宠物房)。

60、这初看似乎十分简单:构造一个集合用来容纳飞机,然。这初看似乎十分简单:构造一个集合用来容纳飞机,然后创建一架新飞机,将其置入集合。对进入空中交通管制后创建一架新飞机,将其置入集合。对进入空中交通管制区的所有飞机都如此处理。至于清除,在一架飞机离开这区的所有飞机都如此处理。至于清除,在一架飞机离开这个区域的时候把它简单地删去即可。个区域的时候把它简单地删去即可。447.对象的创建和存在时间对象的创建和存在时间 但事情并没有这么简单,可能还需要另一套系统来记但事情并没有这么简单,可能还需要另一套系统来记录与飞机有关的数据。当然,和控制器的主要功能不同,录与飞机有关的数据。当然,和控制器的主要功能不

61、同,这些数据的重要性可能一开始并不显露出来。例如,这条这些数据的重要性可能一开始并不显露出来。例如,这条记录反映的可能是离开机场的所有小飞机的飞行计划。所记录反映的可能是离开机场的所有小飞机的飞行计划。所以我们得到了由小飞机组成的另一个集合。一旦创建了一以我们得到了由小飞机组成的另一个集合。一旦创建了一个飞机对象,如果它是一架小飞机,那么也必须把它置入个飞机对象,如果它是一架小飞机,那么也必须把它置入这个集合。然后在系统空闲时期,需对这个集合中的对象这个集合。然后在系统空闲时期,需对这个集合中的对象进行一些后台处理。进行一些后台处理。问题现在显得更复杂了问题现在显得更复杂了:如何才能知道什么时

62、间删除:如何才能知道什么时间删除对象呢?对象呢?用完对象后,系统的其他某些部分可能仍然要发用完对象后,系统的其他某些部分可能仍然要发挥作用挥作用。同样的问题也会在其他大量场合出现,而且在程。同样的问题也会在其他大量场合出现,而且在程序设计系统中(如序设计系统中(如C+),在用完一个对象之后必须明确),在用完一个对象之后必须明确地将其删除,所以问题会变得异常复杂。地将其删除,所以问题会变得异常复杂。457.对象的创建和存在时间对象的创建和存在时间 在在Java中,垃圾收集器在设计时已考虑到了内中,垃圾收集器在设计时已考虑到了内存的释放问题(尽管这并不包括清除一个对象涉及存的释放问题(尽管这并不包

63、括清除一个对象涉及到的其他方面)。到的其他方面)。垃圾收集器垃圾收集器“知道知道”一个对象在一个对象在什么时候不再使用,然后会自动释放那个对象占据什么时候不再使用,然后会自动释放那个对象占据的内存空间的内存空间。采用这种方式,另外加上所有对象都。采用这种方式,另外加上所有对象都从单个根类从单个根类Object继承的事实,而且由于我们只能继承的事实,而且由于我们只能在内存堆中以一种方式创建对象,所以在内存堆中以一种方式创建对象,所以Java的编程的编程要比要比C+的编程简单得多。我们只需要作出少量的的编程简单得多。我们只需要作出少量的抉择,即可克服原先存在的大量障碍。抉择,即可克服原先存在的大量

64、障碍。467.对象的创建和存在时间对象的创建和存在时间 垃圾收集器对效率及灵活性的影响垃圾收集器对效率及灵活性的影响既然这是如此好的一种手段,为什么在既然这是如此好的一种手段,为什么在C+里没有得到充分的里没有得到充分的发挥呢发挥呢?我们当然要为这种编程的方便性付出一定的代价,?我们当然要为这种编程的方便性付出一定的代价,代价就代价就是运行期的开销是运行期的开销。正如早先提到的那样,在。正如早先提到的那样,在C+中,我们可在堆栈中,我们可在堆栈中创建对象。在这种情况下,对象会得以自动清除(但不具有在运中创建对象。在这种情况下,对象会得以自动清除(但不具有在运行期间随心所欲创建对象的灵活性)。行

65、期间随心所欲创建对象的灵活性)。在堆栈中创建对象是为对象在堆栈中创建对象是为对象分配存储空间最有效的一种方式,也是释放那些空间最有效的一种分配存储空间最有效的一种方式,也是释放那些空间最有效的一种方式。在内存堆(方式。在内存堆(Heap)中创建对象可能要付出昂贵得多的代价)中创建对象可能要付出昂贵得多的代价。如果总是从同一个基础类继承,并使所有函数调用都具有如果总是从同一个基础类继承,并使所有函数调用都具有“同质多同质多形形”特征,那么也不可避免地需要付出一定的代价。但垃圾收集器特征,那么也不可避免地需要付出一定的代价。但垃圾收集器是一种特殊的问题,因为我们永远不能确定它什么时候启动或者要是一

66、种特殊的问题,因为我们永远不能确定它什么时候启动或者要花多长的时间。这意味着在花多长的时间。这意味着在Java程序执行期间,存在着一种不连贯程序执行期间,存在着一种不连贯的因素。所以在某些特殊的场合,我们必须避免用它的因素。所以在某些特殊的场合,我们必须避免用它比如在一比如在一个程序的执行必须保持稳定、连贯的时候(通常把它们叫作个程序的执行必须保持稳定、连贯的时候(通常把它们叫作“实时实时程序程序”,尽管并不是所有实时编程问题都要这方面的要求)。,尽管并不是所有实时编程问题都要这方面的要求)。477.对象的创建和存在时间对象的创建和存在时间 C+语言的设计者曾经向语言的设计者曾经向C程序员发出

67、请求程序员发出请求(而且做得非常成功),不要希望在可以使用(而且做得非常成功),不要希望在可以使用C的的任何地方,向语言里加入可能对任何地方,向语言里加入可能对C+的速度或使用的速度或使用造成影响的任何特性。这个目的达到了,但代价就造成影响的任何特性。这个目的达到了,但代价就是是C+的编程不可避免地复杂起来。的编程不可避免地复杂起来。Java比比C+简单,但付出的代价是效率以及一简单,但付出的代价是效率以及一定程度的灵活性定程度的灵活性。但对大多数程序设计问题来说,。但对大多数程序设计问题来说,Java无疑都应是我们的首选。无疑都应是我们的首选。 488.违例控制违例控制 从最古老的程序设计语

68、言开始,错误控制一从最古老的程序设计语言开始,错误控制一直都是设计者们需要解决的一个大问题。由于很难直都是设计者们需要解决的一个大问题。由于很难设计出一套完美的错误控制方案,许多语言干脆将设计出一套完美的错误控制方案,许多语言干脆将问题简单地忽略掉,将其转嫁给库设计人员。对大问题简单地忽略掉,将其转嫁给库设计人员。对大多数错误控制方案来说,最主要的一个问题是它们多数错误控制方案来说,最主要的一个问题是它们严重依赖程序员的警觉性,而不是依赖语言本身的严重依赖程序员的警觉性,而不是依赖语言本身的强制标准。如果程序员不够警惕强制标准。如果程序员不够警惕若比较匆忙,若比较匆忙,这几乎是肯定会发生的这几

69、乎是肯定会发生的程序所依赖的错误控制程序所依赖的错误控制方案便会失效。方案便会失效。498.违例控制违例控制 u“违例控制违例控制”将错误控制方案内置到程序设计语将错误控制方案内置到程序设计语言中,有时甚至内建到操作系统内。言中,有时甚至内建到操作系统内。 uJava的违例控制机制与大多数程序设计语言都有的违例控制机制与大多数程序设计语言都有所不同。因为在所不同。因为在Java中,违例控制模块是从一开中,违例控制模块是从一开始就封装好的,所以必须使用它!始就封装好的,所以必须使用它! 509.多线程多线程 在计算机编程中,一个基本的概念就是同时对多个任在计算机编程中,一个基本的概念就是同时对多

70、个任务加以控制务加以控制。许多程序设计问题都要求程序能够停下手头。许多程序设计问题都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主进程。可以通的工作,改为处理其他一些问题,再返回主进程。可以通过多种途径达到这个目的。最开始的时候,那些拥有机器过多种途径达到这个目的。最开始的时候,那些拥有机器低级知识的程序员编写一些低级知识的程序员编写一些“中断服务例程中断服务例程”,主进程的,主进程的暂停是通过硬件级的中断实现的。尽管这是一种有用的方暂停是通过硬件级的中断实现的。尽管这是一种有用的方法,但编出的程序很难移植,由此造成了另一类的代价高法,但编出的程序很难移植,由此造成了另一类的代价高

71、昂问题。昂问题。有些时候,中断对那些实时性很强的任务来说是很有有些时候,中断对那些实时性很强的任务来说是很有必要的。但还存在其他许多问题,它们只要求将问题划分必要的。但还存在其他许多问题,它们只要求将问题划分进入独立运行的程序片断中,使整个程序能更迅速地响应进入独立运行的程序片断中,使整个程序能更迅速地响应用户的请求。在一个程序中,这些独立运行的片断叫作用户的请求。在一个程序中,这些独立运行的片断叫作“线程线程”(Thread),利用它编程的概念就叫作),利用它编程的概念就叫作“多线程处多线程处理理”。多线程处理一个常见的例子就是用户界面多线程处理一个常见的例子就是用户界面。利用线。利用线程,

72、用户可按下一个按钮,然后程序会立即作出响应,而程,用户可按下一个按钮,然后程序会立即作出响应,而不是让用户等待程序完成了当前任务以后才开始响应。不是让用户等待程序完成了当前任务以后才开始响应。519.多线程多线程 最开始,最开始,线程只是用于分配单个处理器的处理时间的线程只是用于分配单个处理器的处理时间的一种工具一种工具。但假如操作系统本身支持多个处理器,那么每。但假如操作系统本身支持多个处理器,那么每个线程都可分配给一个不同的处理器,真正进入个线程都可分配给一个不同的处理器,真正进入“并行运并行运算算”状态。从程序设计语言的角度看,多线程操作最有价状态。从程序设计语言的角度看,多线程操作最有

73、价值的特性之一就是程序员不必关心到底使用了多少个处理值的特性之一就是程序员不必关心到底使用了多少个处理器。程序在逻辑意义上被分割为数个线程;假如机器本身器。程序在逻辑意义上被分割为数个线程;假如机器本身安装了多个处理器,那么程序会运行得更快,毋需作出任安装了多个处理器,那么程序会运行得更快,毋需作出任何特殊的调校。何特殊的调校。根据前面的论述,大家可能感觉线程处理非常简单。根据前面的论述,大家可能感觉线程处理非常简单。但必须注意一个问题:但必须注意一个问题:共享资源共享资源!如果有多个线程同时运!如果有多个线程同时运行,而且它们试图访问相同的资源,就会遇到一个问题。行,而且它们试图访问相同的资

74、源,就会遇到一个问题。举个例子举个例子来说,两个进程不能将信息同时发送给一台打印来说,两个进程不能将信息同时发送给一台打印机。为解决这个问题,对那些可共享的资源来说(比如打机。为解决这个问题,对那些可共享的资源来说(比如打印机),它们在使用期间必须进入锁定状态。所以一个线印机),它们在使用期间必须进入锁定状态。所以一个线程可将资源锁定,在完成了它的任务后,再解开(释放)程可将资源锁定,在完成了它的任务后,再解开(释放)这个锁,使其他线程可以接着使用同样的资源。这个锁,使其他线程可以接着使用同样的资源。529.多线程多线程 Java的多线程机制已内建到语言中的多线程机制已内建到语言中,这使一个,

75、这使一个可能较复杂的问题变得简单起来。对多线程处理的可能较复杂的问题变得简单起来。对多线程处理的支持是在对象这一级支持的,所以一个执行线程可支持是在对象这一级支持的,所以一个执行线程可表达为一个对象。表达为一个对象。Java也提供了有限的资源锁定方也提供了有限的资源锁定方案案。它能锁定任何对象占用的内存(内存实际是多。它能锁定任何对象占用的内存(内存实际是多种共享资源的一种),所以同一时间只能有一个线种共享资源的一种),所以同一时间只能有一个线程使用特定的内存空间。为达到这个目的,需要使程使用特定的内存空间。为达到这个目的,需要使用用synchronized关键字。其他类型的资源必须由程关键字

76、。其他类型的资源必须由程序员明确锁定,这通常要求程序员创建一个对象,序员明确锁定,这通常要求程序员创建一个对象,用它代表一把锁,所有线程在访问那个资源时都必用它代表一把锁,所有线程在访问那个资源时都必须检查这把锁。须检查这把锁。 539.多线程多线程 u从程序设计语言的角度看,多线程操作最有价值从程序设计语言的角度看,多线程操作最有价值的特性之一就是程序员不必关心到底使用了多少的特性之一就是程序员不必关心到底使用了多少个处理器。个处理器。 u程序在逻辑意义上被分割为数个线程;假如机器程序在逻辑意义上被分割为数个线程;假如机器本身安装了多个处理器,那么程序会运行得更快,本身安装了多个处理器,那么

77、程序会运行得更快,毋需作出任何特殊的调校。毋需作出任何特殊的调校。 u如果有多个线程同时运行,而且它们试图访问相如果有多个线程同时运行,而且它们试图访问相同的资源,就会遇到一个问题。同的资源,就会遇到一个问题。 uJava的多线程机制已内建到语言中,这使一个可的多线程机制已内建到语言中,这使一个可能较复杂的问题变得简单起来。能较复杂的问题变得简单起来。 5410.永久性永久性 u创建一个对象后,只要我们需要,它就会一直存创建一个对象后,只要我们需要,它就会一直存在下去。但在程序结束运行时,对象的在下去。但在程序结束运行时,对象的“生存期生存期”也会宣告结束。尽管这一现象表面上非常合理,也会宣告

78、结束。尽管这一现象表面上非常合理,但深入追究就会发现,假如在程序停止运行以后,但深入追究就会发现,假如在程序停止运行以后,对象也能继续存在,并能保留它的全部信息,那对象也能继续存在,并能保留它的全部信息,那么在某些情况下将是一件非常有价值的事情。下么在某些情况下将是一件非常有价值的事情。下次启动程序时,对象仍然在那里,里面保留的信次启动程序时,对象仍然在那里,里面保留的信息仍然是程序上一次运行时的那些信息。当然,息仍然是程序上一次运行时的那些信息。当然,可以将信息写入一个文件或者数据库,从而达到可以将信息写入一个文件或者数据库,从而达到相同的效果。但尽管可将所有东西都看作一个对相同的效果。但尽

79、管可将所有东西都看作一个对象,如果能将对象声明成象,如果能将对象声明成“永久性永久性”,并令其为,并令其为我们照看其他所有细节,无疑也是一件相当方便我们照看其他所有细节,无疑也是一件相当方便的事情。的事情。 5511. Java和因特网和因特网 u客户机服务器客户机服务器 uWeb是一个巨大的服务器是一个巨大的服务器 ,是一套规模巨大的,是一套规模巨大的客户机服务器系统客户机服务器系统 5612.分析和设计分析和设计 面向对象的范式是思考程序设计时一种新的、而且全面向对象的范式是思考程序设计时一种新的、而且全然不同的方式,许多人最开始都会在如何构造一个项目上然不同的方式,许多人最开始都会在如何

80、构造一个项目上皱起了眉头。事实上,我们可以作出一个皱起了眉头。事实上,我们可以作出一个“好好”的设计,的设计,它能充分利用它能充分利用OOP提供的所有优点。提供的所有优点。有关有关OOP分析与设计的书籍大多数都不尽如人意。如分析与设计的书籍大多数都不尽如人意。如果不能说得简单和直接,一定没多少人喜欢看这方面的内果不能说得简单和直接,一定没多少人喜欢看这方面的内容。毕竟,容。毕竟,OOP的全部宗旨就是让软件开发的过程变得更的全部宗旨就是让软件开发的过程变得更加容易加容易。尽管这可能影响了那些喜欢解决复杂问题的人的。尽管这可能影响了那些喜欢解决复杂问题的人的生计,但为什么不从一开始就把事情弄得简单

81、些呢?因此,生计,但为什么不从一开始就把事情弄得简单些呢?因此,希望能从开始就为大家打下一个良好的基础,尽可能清楚希望能从开始就为大家打下一个良好的基础,尽可能清楚分析与设计的问题。分析与设计的问题。Grady BoochObject-Oriented Design with Applications,第2版,Wiely & Sons于1996年出版 5712.分析和设计分析和设计 u不要迷失不要迷失 在整个开发过程中,最重要的事情就是:不要将自己迷失!但事实在整个开发过程中,最重要的事情就是:不要将自己迷失!但事实上这种事情很容易发生。大多数方法都设计用来解决最大范围内的上这种事情很容易发生

82、。大多数方法都设计用来解决最大范围内的问题。当然,也存在一些特别困难的项目,需要作者付出更为艰辛问题。当然,也存在一些特别困难的项目,需要作者付出更为艰辛的努力,或者付出更大的代价。但是,大多数项目都是比较的努力,或者付出更大的代价。但是,大多数项目都是比较“常规常规”的,所以一般都能作出成功的分析与设计,而且只需用到推荐的的,所以一般都能作出成功的分析与设计,而且只需用到推荐的一小部分方法。但无论多么有限,某些形式的处理总是有益的,这一小部分方法。但无论多么有限,某些形式的处理总是有益的,这可使整个项目的开发更加容易,总比直接了当开始编码好!可使整个项目的开发更加容易,总比直接了当开始编码好

83、!也就是说,假如你正在考察一种特殊的方法,其中包含了大量细节,也就是说,假如你正在考察一种特殊的方法,其中包含了大量细节,并推荐了许多步骤和文档,那么仍然很难正确判断自己该在何时停并推荐了许多步骤和文档,那么仍然很难正确判断自己该在何时停止。时刻提醒自己注意以下几个问题:止。时刻提醒自己注意以下几个问题:(1) 对象是什么?对象是什么?(怎样将自己的项目分割成一系列单独的组件?)(怎样将自己的项目分割成一系列单独的组件?)(2) 它们的接口是什么?它们的接口是什么?(需要将什么消息发给每一个对象?)(需要将什么消息发给每一个对象?)在确定了对象和它们的接口后,便可着手编写一个程序。出于对多在确

84、定了对象和它们的接口后,便可着手编写一个程序。出于对多方面原因的考虑,可能还需要比这更多的说明及文档,但要求掌握方面原因的考虑,可能还需要比这更多的说明及文档,但要求掌握的资料绝对不能比这还少。的资料绝对不能比这还少。5812.分析和设计分析和设计 u阶段阶段0:拟出一个计划:拟出一个计划 第一步是决定在后面的过程中采取哪些步骤。这听起来似乎很简单第一步是决定在后面的过程中采取哪些步骤。这听起来似乎很简单(事实上,我们这儿说的一切都似乎很简单),但很常见的一种情(事实上,我们这儿说的一切都似乎很简单),但很常见的一种情况是:有些人甚至没有进入阶段况是:有些人甚至没有进入阶段1,便忙忙慌慌地开始

85、编写代码。,便忙忙慌慌地开始编写代码。如果你的计划本来就是如果你的计划本来就是“直接开始开始编码直接开始开始编码”,那样做当然也无可,那样做当然也无可非议(若对自己要解决的问题已有很透彻的理解,便可考虑那样做)非议(若对自己要解决的问题已有很透彻的理解,便可考虑那样做)。但最低程度也应同意自己该有个计划。但最低程度也应同意自己该有个计划。在这个阶段,可能要决定一些必要的附加处理结构。但非常不幸,在这个阶段,可能要决定一些必要的附加处理结构。但非常不幸,有些程序员写程序时喜欢随心所欲,他们认为有些程序员写程序时喜欢随心所欲,他们认为“该完成的时候自然该完成的时候自然会完成会完成”。这样做刚开始可

86、能不会有什么问题,但我觉得假如能在。这样做刚开始可能不会有什么问题,但我觉得假如能在整个过程中设置几个标志,或者整个过程中设置几个标志,或者“路标路标”,将更有益于你集中注意,将更有益于你集中注意力。这恐怕比单纯地为了力。这恐怕比单纯地为了“完成工作完成工作”而工作好得多。至少,在达而工作好得多。至少,在达到了一个又一个的目标,经过了一个接一个的路标以后,可对自己到了一个又一个的目标,经过了一个接一个的路标以后,可对自己的进度有清晰的把握,干劲也会相应地提高,不会产生的进度有清晰的把握,干劲也会相应地提高,不会产生“路遥漫漫路遥漫漫无期无期”的感觉。的感觉。5912.分析和设计分析和设计 u阶

87、段阶段1:要制作什么?:要制作什么? 需求分析的意思是需求分析的意思是“建立一系列规则,根据它判断任务什么时候完建立一系列规则,根据它判断任务什么时候完成,以及客户怎样才能满意成,以及客户怎样才能满意”。系统规格则表示。系统规格则表示“这里是一些具体这里是一些具体的说明,让你知道程序需要做什么(而不是怎样做)才能满足要求的说明,让你知道程序需要做什么(而不是怎样做)才能满足要求”。需求分析实际就是你和客户之间的一份合约(即使客户就在本。需求分析实际就是你和客户之间的一份合约(即使客户就在本公司内部工作,或者是其他对象及系统)。系统规格是对所面临问公司内部工作,或者是其他对象及系统)。系统规格是

88、对所面临问题的最高级别的一种揭示,我们依据它判断任务是否完成,以及需题的最高级别的一种揭示,我们依据它判断任务是否完成,以及需要花多长的时间。由于这些都需要取得参与者的一致同意,所以我要花多长的时间。由于这些都需要取得参与者的一致同意,所以我建议尽可能地简化它们建议尽可能地简化它们最好采用列表和基本图表的形式最好采用列表和基本图表的形式以以节省时间。可能还会面临另一些限制,需要把它们扩充成为更大的节省时间。可能还会面临另一些限制,需要把它们扩充成为更大的文档。文档。我们特别要注意将我们特别要注意将重点放在这一阶段的核心问题上,不要纠缠于细重点放在这一阶段的核心问题上,不要纠缠于细枝末节枝末节。

89、这个核心问题就是:决定采用什么系统。对这个问题,最。这个核心问题就是:决定采用什么系统。对这个问题,最有价值的工具就是一个名为有价值的工具就是一个名为“使用条件使用条件”的集合。对那些采用的集合。对那些采用“假假如如,系统该怎样做?,系统该怎样做?”形式的问题,这便是最有说服力的回答。形式的问题,这便是最有说服力的回答。例如,例如,“假如客户需要提取一张现金支票,但当时又没有这么多的假如客户需要提取一张现金支票,但当时又没有这么多的现金储备,那么自动取款机该怎样反应?现金储备,那么自动取款机该怎样反应?”对这个问题,对这个问题,“使用条使用条件件”可以指示自动取款机在那种可以指示自动取款机在那

90、种“条件条件”下的正确操作。下的正确操作。6012.分析和设计分析和设计 u阶段阶段2:如何构建?:如何构建?在这一阶段,必须拿出一套设计方案,并解释其中包含的在这一阶段,必须拿出一套设计方案,并解释其中包含的各类对象在外观上是什么样子,以及相互间是如何沟通的。各类对象在外观上是什么样子,以及相互间是如何沟通的。此时可考虑采用一种特殊的图表工具:此时可考虑采用一种特殊的图表工具:“统一建模语言统一建模语言”(UML)。请到去下载一份)。请到去下载一份UML规格书。作为第规格书。作为第1阶段阶段中的描述工具,中的描述工具,UML也是很有帮助的。此外,还可用它也是很有帮助的。此外,还可用它在第在第

91、2阶段中处理一些图表(如流程图)。当然并非一定阶段中处理一些图表(如流程图)。当然并非一定要使用要使用UML,但它对你会很有帮助,特别是在希望描绘,但它对你会很有帮助,特别是在希望描绘一张详尽的图表,让许多人在一起研究的时候。除一张详尽的图表,让许多人在一起研究的时候。除UML外,还可选择对对象以及它们的接口进行文字化描述,但外,还可选择对对象以及它们的接口进行文字化描述,但这种方法非常原始,发挥的作用亦较有限。这种方法非常原始,发挥的作用亦较有限。6112.分析和设计分析和设计 u阶段阶段3:开始创建:开始创建现在进入的是你可能最感兴趣的阶段。由于手头上有一个计划现在进入的是你可能最感兴趣的

92、阶段。由于手头上有一个计划无论它有多么简要,而且在正式编码前掌握了正确的设计结构,所无论它有多么简要,而且在正式编码前掌握了正确的设计结构,所以会发现接下去的工作比一开始就埋头写程序要简单得多。而这正以会发现接下去的工作比一开始就埋头写程序要简单得多。而这正是我们想达到的目的。让代码做到我们想做的事情,这是所有程序是我们想达到的目的。让代码做到我们想做的事情,这是所有程序项目最终的目标。但切不要急功冒进,否则只有得不偿失。根据经项目最终的目标。但切不要急功冒进,否则只有得不偿失。根据经验,最后先拿出一套较为全面的方案,使其尽可能设想周全,能满验,最后先拿出一套较为全面的方案,使其尽可能设想周全

93、,能满足尽可能多的要求。感觉上,编程更象一门艺术,不能只是作为技足尽可能多的要求。感觉上,编程更象一门艺术,不能只是作为技术活来看待。所有付出最终都会得到回报。作为真正的程序员,这术活来看待。所有付出最终都会得到回报。作为真正的程序员,这并非可有可无的一种素质。全面的思考、周密的准备、良好的构造并非可有可无的一种素质。全面的思考、周密的准备、良好的构造不仅使程序更易构建与调试,也使其更易理解和维护,而那正是一不仅使程序更易构建与调试,也使其更易理解和维护,而那正是一套软件赢利的必要条件。套软件赢利的必要条件。构建好系统,并令其运行起来后,必须进行实际检验,以前做的那构建好系统,并令其运行起来后

94、,必须进行实际检验,以前做的那些需求分析和系统规格便可派上用场了。全面地考察自己的程序,些需求分析和系统规格便可派上用场了。全面地考察自己的程序,确定提出的所有要求均已满足。确定提出的所有要求均已满足。现在一切似乎都该结束了?是吗?现在一切似乎都该结束了?是吗?6212.分析和设计分析和设计 u阶段阶段4:校订:校订事实上,整个开发周期还没有结束,现在进入的是传统意义上称为事实上,整个开发周期还没有结束,现在进入的是传统意义上称为“维护维护”的一个阶段。的一个阶段。“维护维护”是一个比较暧昧的称呼,可用它表是一个比较暧昧的称呼,可用它表示从示从“保持它按设想的轨道运行保持它按设想的轨道运行”、

95、“加入客户从前忘了声明的功加入客户从前忘了声明的功能能”或者更传统的或者更传统的“除掉暴露出来的一切臭虫除掉暴露出来的一切臭虫”等等意思。所以大等等意思。所以大家对家对“维护维护”这个词产生了许多误解,有的人认为:凡是需要这个词产生了许多误解,有的人认为:凡是需要“维维护护”的东西,必定不是好的,或者是有缺陷的!因为这个词说明你的东西,必定不是好的,或者是有缺陷的!因为这个词说明你实际构建的是一个非常实际构建的是一个非常“原始原始”的程序,以后需要频繁地作出改动、的程序,以后需要频繁地作出改动、添加新的代码或者防止它的落后、退化等。因此,我们需要用一个添加新的代码或者防止它的落后、退化等。因此

96、,我们需要用一个更合理的词语来称呼以后需要继续的工作。更合理的词语来称呼以后需要继续的工作。这个词便是这个词便是“校订校订”。换言之,。换言之,“你第一次做的东西并不完善,所你第一次做的东西并不完善,所以需为自己留下一个深入学习、认知的空间,再回过头去作一些改以需为自己留下一个深入学习、认知的空间,再回过头去作一些改变变”。对于要解决的问题,随着对它的学习和了解愈加深入,可能。对于要解决的问题,随着对它的学习和了解愈加深入,可能需要作出大量改动。进行这些工作的一个动力是随着不断的改革优需要作出大量改动。进行这些工作的一个动力是随着不断的改革优化,终于能够从自己的努力中得到回报,无论这需要经历一

97、个较短化,终于能够从自己的努力中得到回报,无论这需要经历一个较短还是较长的时期。还是较长的时期。6312.分析和设计分析和设计 通过校订,可创建出至少接近自己设想的东西。然后从整体上观察通过校订,可创建出至少接近自己设想的东西。然后从整体上观察自己的作品,把它与自己的要求比较,看看还短缺什么。然后就可自己的作品,把它与自己的要求比较,看看还短缺什么。然后就可以从容地回过头去,对程序中不恰当的部分进行重新设计和重新实以从容地回过头去,对程序中不恰当的部分进行重新设计和重新实现。在最终得到一套恰当的方案之前,可能需要解决一些不能回避现。在最终得到一套恰当的方案之前,可能需要解决一些不能回避的问题,

98、或者至少解决问题的一个方面。而且一般要多的问题,或者至少解决问题的一个方面。而且一般要多“校订校订”几几次才行(次才行(“设计范式设计范式”在这里可起到很大的帮助作用)。在这里可起到很大的帮助作用)。构建一套系统时,构建一套系统时,“校订校订”几乎是不可避免的。我们需要不断地对几乎是不可避免的。我们需要不断地对比自己的需求,了解系统是否自己实际所需要的。有时只有实际看比自己的需求,了解系统是否自己实际所需要的。有时只有实际看到系统,才能意识到自己需要解决一个不同的问题。若认为这种形到系统,才能意识到自己需要解决一个不同的问题。若认为这种形式的校订必然会发生,那么最好尽快拿出自己的第一个版本,检

99、查式的校订必然会发生,那么最好尽快拿出自己的第一个版本,检查它是否自己希望的,使自己的思想不断趋向成熟。它是否自己希望的,使自己的思想不断趋向成熟。反复的反复的“校订校订”同同“递增开发递增开发”有关密不可分的关系。递增开发意有关密不可分的关系。递增开发意味着先从系统的核心入手,将其作为一个框架实现,以后要在这个味着先从系统的核心入手,将其作为一个框架实现,以后要在这个框架的基础上逐渐建立起系统剩余的部分。随后,将准备提供的各框架的基础上逐渐建立起系统剩余的部分。随后,将准备提供的各种功能(特性)一个接一个地加入其中。这里最考验技巧的是架设种功能(特性)一个接一个地加入其中。这里最考验技巧的是

100、架设起一个能方便扩充所有目标特性的一个框架。这样做的好处在于一起一个能方便扩充所有目标特性的一个框架。这样做的好处在于一旦令核心框架运作起来,要加入的每一项特性就象它自身内的一个旦令核心框架运作起来,要加入的每一项特性就象它自身内的一个小项目,而非大项目的一部分。此外,开发或维护阶段合成的新特小项目,而非大项目的一部分。此外,开发或维护阶段合成的新特性可以更方便地加入。性可以更方便地加入。OOP之所以提供了对递增开发的支持,是由之所以提供了对递增开发的支持,是由于假如程序设计得好,每一次递增都可以成为完善的对象或者对象于假如程序设计得好,每一次递增都可以成为完善的对象或者对象组。组。6412.

101、分析和设计分析和设计 u计划的回报计划的回报如果没有仔细拟定的设计图,当然不可能建起一所房子。如果没有仔细拟定的设计图,当然不可能建起一所房子。如建立的是一所狗舍,尽管设计图可以不必那么详尽,但如建立的是一所狗舍,尽管设计图可以不必那么详尽,但仍然需要一些草图,以做到心中有数。软件开发则完全不仍然需要一些草图,以做到心中有数。软件开发则完全不同,它的同,它的“设计图设计图”(计划)必须详尽而完备。在很长的(计划)必须详尽而完备。在很长的一段时间里,人们在开发过程中并没有太多的结构,但那一段时间里,人们在开发过程中并没有太多的结构,但那些大型项目很容易就会遭致失败。通过不断的摸索,人们些大型项目

102、很容易就会遭致失败。通过不断的摸索,人们掌握了数量众多的结构和详细资料。但它们的使用却使人掌握了数量众多的结构和详细资料。但它们的使用却使人提心吊胆提心吊胆似乎需要把自己的大多数时间花在编写文档似乎需要把自己的大多数时间花在编写文档上,而没有多少时间来编程上,而没有多少时间来编程(经常如此)。希望这里为大(经常如此)。希望这里为大家讲述的一切能提供一条折衷的道路。需要采取一种最适家讲述的一切能提供一条折衷的道路。需要采取一种最适合自己需要(以及习惯)的方法。不管制订出的计划有多合自己需要(以及习惯)的方法。不管制订出的计划有多么小,但与完全没有计划相比,一些形式的计划会极大改么小,但与完全没有

103、计划相比,一些形式的计划会极大改善你的项目。请记住:善你的项目。请记住:根据估计,没有计划的根据估计,没有计划的50以上的以上的项目都会失败!项目都会失败!65二、二、Java 介绍介绍u0.Write Once,Run Anywhereu1.什么是什么是Java编程语言编程语言u2.Java编程语言的主要目标编程语言的主要目标u3.Java虚拟机虚拟机u4.垃圾收集垃圾收集u5.代码的安全性代码的安全性u6.一个基本的一个基本的Java应用程序应用程序u7.类和包类和包u8.使用使用Java API文档文档660.Write Once,Run Anywhere671.什么是什么是Java编程

104、语言编程语言Java是:是:u一种编程语言一种编程语言u一种开发环境一种开发环境u一种应用环境一种应用环境u一种部署环境一种部署环境u句法与句法与C+相似,语义与相似,语义与Small Talk相似相似u用来开发用来开发applets,又用来开发,又用来开发applications 682.Java编程语言的主要目标编程语言的主要目标 u提供一种解释环境为:提供一种解释环境为:t提高开发速度提高开发速度t代码可移植性代码可移植性t使用户能运行不止一个活动线程使用户能运行不止一个活动线程t当程序运行时,能动态支持程序改变当程序运行时,能动态支持程序改变u提供更好的安全性提供更好的安全性 692.

105、Java编程语言的主要目标编程语言的主要目标设计设计Java编程语言的主要目标是:编程语言的主要目标是:u提供一种易于编程的语言提供一种易于编程的语言u消除其它语言在诸如指针运算和存储器管理方面消除其它语言在诸如指针运算和存储器管理方面影响健壮性的缺陷。影响健壮性的缺陷。u利用面向对象的概念使程序真正地成为可视化程利用面向对象的概念使程序真正地成为可视化程序序u为使代码尽可能清晰合理、简明流畅提供了一种为使代码尽可能清晰合理、简明流畅提供了一种方法方法 702.Java编程语言的主要目标编程语言的主要目标下列特性使这些目标付诸实现:下列特性使这些目标付诸实现:uJava虚拟机(虚拟机(JVM)

106、u垃圾收集垃圾收集u代码安全性代码安全性713.Java虚拟机虚拟机 u提供硬件平台规范提供硬件平台规范u解读独立于平台的已编译的字节码解读独立于平台的已编译的字节码u可当作软件或硬件来实现可当作软件或硬件来实现u可在可在Java技术开发工具或技术开发工具或Web浏览器上实现浏览器上实现 723.Java虚拟机虚拟机JVM为下列各项做出了定义为下列各项做出了定义u指令集(中央处理器指令集(中央处理器CPU )u注册集注册集u类文件格式类文件格式u栈栈u垃圾收集堆垃圾收集堆u存储区存储区 733.Java虚拟机虚拟机u由保持适当类型约束的字节码形成代码由保持适当类型约束的字节码形成代码u大部分类

107、型检查在编译代码时完成大部分类型检查在编译代码时完成u每个由每个由SUN TM 批准的批准的JVM必须能够运行任何从必须能够运行任何从属类文件属类文件 744.垃圾收集垃圾收集 u不再需要的分配存储器应取消分配不再需要的分配存储器应取消分配u在其它语言中,取消分配是程序员的责任在其它语言中,取消分配是程序员的责任uJava编程语言提供了一种系统级线程以跟踪存储编程语言提供了一种系统级线程以跟踪存储区分配区分配u垃圾收集垃圾收集t可检查和释放不再需要的存储器可检查和释放不再需要的存储器t可自动完成上述工作可自动完成上述工作t可在可在JVM实现周期中,产生意想不到的变化实现周期中,产生意想不到的变

108、化755.代码的安全性代码的安全性 765.代码的安全性代码的安全性Java运行环境运行环境执行三大任务:执行三大任务:u加载代码由类加载器执行加载代码由类加载器执行u校验代码由字节码校验器执行校验代码由字节码校验器执行u执行代码由运行时的解释器执行执行代码由运行时的解释器执行775.代码的安全性代码的安全性字节码校验字节码校验 可保证:可保证:u代码符合代码符合JVM规范规范u代码不破坏系统完整性代码不破坏系统完整性u代码不会引起操作数栈上溢或下溢代码不会引起操作数栈上溢或下溢u所有操作代码的参数类型的准确性所有操作代码的参数类型的准确性u无非法数据转换(整数到指针的转换)无非法数据转换(整

109、数到指针的转换)786.一个基本的一个基本的Java应用程序应用程序 1./ 2./ Sample HelloWorld application 3./ 4.public class HelloWorldApp 5. public static void main (String args) 6. System.out.println (Hello World!); 7. 8. 以上程序行是在你的屏幕上打印以上程序行是在你的屏幕上打印“Hello World!”所需所需的最少组件。的最少组件。 796.一个基本的一个基本的Java应用程序应用程序 源文件布局源文件布局 包含三个包含三个“顶级顶

110、级”要素要素u一个可选择的包声明一个可选择的包声明u任意数量的输入语句任意数量的输入语句u类和界面声明类和界面声明 806.一个基本的一个基本的Java应用程序应用程序编译并运行编译并运行HelloWorldApp u编译编译HelloWorldApp.java javac HelloworldApp.javau运行应用程序运行应用程序 java HelloWorldAppu判定编译和运行的共同错误判定编译和运行的共同错误 816.一个基本的一个基本的Java应用程序应用程序827.类和包类和包 u什么是类和包?什么是类和包?uJava类库中的几个重要包类库中的几个重要包tjava.lang包

111、含一些形成语言核心的类,如包含一些形成语言核心的类,如String、Math、Integer和和Thread。tjava.awt包含了构成抽象窗口工具包(包含了构成抽象窗口工具包(AWT)的类,)的类,这个包被用来构建和管理应用程序的图形用户界面。这个包被用来构建和管理应用程序的图形用户界面。tjava.applet包含了可执行包含了可执行applet特殊行为的类。特殊行为的类。包含执行与网络相关的操作的类和处理接口及包含执行与网络相关的操作的类和处理接口及统一资源定位器统一资源定位器(URLs)的类。的类。tjava.io包含处理包含处理I/O文件的类。文件的类。tjava.util包含为任

112、务设置的实用程序类,如随机数发生、包含为任务设置的实用程序类,如随机数发生、定义系统特性和使用与日期日历相关的函数。定义系统特性和使用与日期日历相关的函数。 838.使用使用Java API文档文档 u一组超文本标识语言一组超文本标识语言(HTML)文件提供了有关文件提供了有关API的信息的信息u一个包包含了对所有类信息的超链接一个包包含了对所有类信息的超链接u一个类文档包括类层次、一个类描述、一组成一个类文档包括类层次、一个类描述、一组成员变量和构造函数等员变量和构造函数等 848.使用使用Java API文档文档一个类文档的主要部分包括一个类文档的主要部分包括:u类层次类层次u类和类的一般目的描述类和类的一般目的描述u成员变量列表成员变量列表u构造函数列表构造函数列表u方法列表方法列表u变量详细列表及目的和用途的描述变量详细列表及目的和用途的描述u构造函数详细列表及描述构造函数详细列表及描述u方法详细列表及描述方法详细列表及描述85

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号