Java编程思想-第1章 对象导论(要点)
我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是 整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来......除非 赞成这个协定中规定的有关语言信息的组织和分类,否则我们根本无法交谈.
「你想想 90 年代的互联网泡沫,以及我们从中得到的所有伟大的基础设施,」Dixon 说,「你基本上是接受了这些成果,并将其缩小到应用程序的大小。」http://baijiahao.baidu.com/s?id=1593527286069505905
1.1 抽象过程
所有编程语言都提供抽象机制。可以认为,人们所能够解决的问题的复杂性直接取决于抽 象的类型和质量。所谓的“类型”是指“所抽象的是什么?”汇编语言是对底层机器的轻微抽 象。接着出现的许多所谓“命令式”语言(如 FORTRAN、 BASIC、C等)都是对汇编语言的抽 象。这些语言在汇编语言基础上有了大幅的改进,但是它们所作的主要抽象仍要求在解决问题 时要基于计算机的结构,而不是基于所要解决的问题的结构来考虑。程序员必须建立起在机器 模型(位于“解空间”内,这是你对问题建模的地方,例如计算机)和实际待解问题的模型 (位于“问题空间”内,这是问题存在的地方,例如一项业务)之间的关联。建立这种映射是费 力的,而且这不属于编程语言所固有的功能,这使得程序难以编写,并且维护代价高昂,同时 也产生了作为副产物的整个“编程方法”行业。
Alan Kay曾经总结了第一个成功的面向对象语言、同时也是Java所基于的语言之一的 Smalltalk的五个基本特性,这些特性表现了一种纯粹的面向对象程序设计方式:
1)万物皆为对象。将对象视为奇特的变量,它可以存储数据,除此之外,你还可以要求它 在自身上执行操作。理论上讲,你可以抽取待求解问题的任何概念化构件(狗、建筑物、服务 等),将其表示为程序中的对象。
2)程序是对象的集合,它们通过发送消息来告知彼此所要做的。要想请求一个对象,就必 须对该对象发送一条消息。更具体地说,可以把消息想像为对某个特定对象的方法的调用请求。
3)每个对象都有自己的由其他对象所构成的存储。换句话说,可以通过创建包含现有对象 的包的方式来创建新类型的对象。因此,可以在程序中构建复杂的体系,同时将其复杂性隐藏 在对象的简单性背后。
4)每个对象都拥有其类型。按照通用的说法,“每个对象都是某个类( class)的一个实例 instance)”,这里“类”就是“类型”的同义词。每个类最重要的区别于其他类的特性就是 可以发送什么样的消息给它”。
5)某一特定类型的所有对象都可以接收同样的消息。这是一句意味深长的表述,你在稍后 便会看到。因为“圆形”类型的对象同时也是“几何形”类型的对象,所以一个“圆形”对象 必定能够接受发送给“几何形”对象的消息。这意味着可以编写与“几何形”交互并自动处理 所有与几何形性质相关的事物的代码。这种可替代性( substitutability)是OoP中最强有力的概 念之一 Booch对对象提出了一个更加简洁的描述:对象具有状态、行为和标识。这意味着每一个对 象都可以拥有内部数据(它们给出了该对象的状态)和方法(它们产生行为),并且每一个对象 都可以唯一地与其他对象区分开来,具体说来,就是每一个对象在内存中都有一个唯一的地址
1.2 每个对象都有一个接口
亚里士多德大概是第一个深入研究类型(type)的哲学家,他曾提出过鱼类和鸟类这样的概 念。所有的对象都是唯一的,但同时也是具有相同的特性和行为的对象所归属的类的一部分。
1.3 每个对象都提供服务
当正在试图开发或理解一个程序设计时,最好的方法之一就是将对象想像为“服务提供者”。 程序本身将向用户提供服务,它将通过调用其他对象提供的服务来实现这一目的。你的目标就 是去创建(或者最好是在现有代码库中寻找)能够提供理想的服务来解决问题的一系列对象。 着手从事这件事的一种方式就是问一下自己:“如果我可以将问题从表象中抽取出来,那么 什么样的对象可以马上解决我的问题呢?”例如,假设你正在创建一个簿记系统,那么可以想 像,系统应该具有某些包括了预定义的簿记输入屏幕的对象,一个执行簿记计算的对象集合, 以及一个处理在不同的打印机上打印支票和开发票的对象。也许上述对象中的某些已经存在了, 但是对于那些并不存在的对象,它们看起来像什么样子?它们能够提供哪些服务?它们需要哪 些对象才能履行它们的义务?如果持续这样做,那么最终你会说“那个对象看起来很简单,可 以坐下来写代码了”,或者会说“我肯定那个对象已经存在了”。这是将问题分解为对象集合的 种合理方式。
1.4 被隐藏的具体实现
将程序开发人员按照角色分为类创建者(那些创建新数据类型的程序员)和客户端程序员 (那些在其应用中使用数据类型的类消费者)是大有裨益的。客户端程序员的目标是收集各种用 来实现快速应用开发的类。类创建者的目标是构建类,这种类只向客户端程序员暴露必需的部 分,而隐藏其他部分。
1.5 复用具体实现
旦类被创建并被测试完,那么它就应该(在理想情况下)代表一个有用的代码单元。事 实证明,这种复用性并不容易达到我们所希望的那种程度,产生一个可复用的对象设计需要丰 富的经验和敏锐的洞察力。但是一旦你有了这样的设计,它就可供复用。代码复用是面向对象 程序设计语言所提供的最了不起的优点之一。
1.6 继承
对象这种观念,本身就是十分方便的工具,使得你可以通过概念将数据和功能封装到一起, 因此可以对问题空间的观念给出恰当的表示,而不用受制于必须使用底层机器语言。这些概念 用关键字clas表示,它们形成了编程语言中的基本单位。
1.7 伴随多态的可互换对象
在处理类型的层次结构时,经常想把一个对象不当作它所属的特定类型来对待,而是将其 当作其基类的对象来对待。这使得人们可以编写出不依赖于特定类型的代码。在“几何形”的 例子中,方法操作的都是泛化( generic)的形状,而不关心它们是圆形、正方形、三角形还是 其他什么尚未定义的形状。所有的几何形状都可以被绘制、擦除和移动,所以这些方法都是直 接对一个几何形对象发送消息;它们不用担心对象将如何处理消息。
1.8 单根继承结构
在OOP中,自C++面世以来就已变得非常瞩目的一个问题就是,是否所有的类最终都继承 自单一的基类。在Java中(事实上还包括除C++以外的所有OOP语言),答案是yes,这个终极基 类的名字就是 Object事实证明,单根继承结构带来了很多好处。
1.9 容器
通常说来,如果不知道在解决某个特定问题时需要多少个对象,或者它们]将存活多久,那 么就不可能知道如何存储这些对象。如何才能知道需要多少空间来创建这些对象呢?答案是你 不可能知道,因为这类信息只有在运行时才能获得。 对于面向对象设计中的大多数问题而言,这个问题的解决方案似乎过于轻率:创建另一种 对象类型。这种新的对象类型持有对其他对象的引用。当然,你可以用在大多数语言中都有的 数组类型来实现相同的功能。但是这个通常被称为容器(也称为集合,不过Java类库以不同的 含义使用“集合”这个术语,所以本书将使用“容器”这个词)的新对象,在任何需要时都可 扩充自己以容纳你置于其中的所有东西。因此不需要知道将来会把多少个对象置于容器中,只 需要创建一个容器对象,然后让它处理所有细节。
1.10 对象的创建和生命期
在使用对象时,最关键的问题之一便是它们的生成和销毁方式。每个对象为了生存都需要 资源,尤其是内存。当我们不再需要一个对象时,它必须被清理掉,使其占有的资源可以被释 放和重用。在相对简单的编程情况下,怎样清理对象看起来似乎不是什么挑战:你创建了对象, 根据需要使用它,然后它应该被销毁。然而,你很可能会遇到相对复杂的情况。
1.11 异常处理:处理错误
自从编程语言问世以来,错误处理就始终是最困难的问题之一。因为设计一个良好的错误 处理机制非常困难,所以许多语言直接略去这个问题,将其交给程序库设计者处理,而这些设 计者也只是提出了一些不彻底的方法,这些方法可用于许多很容易就可以绕过此问题的场合, 而且其解决方式通常也只是忽略此问题。大多数错误处理机制的主要问题在于,它们都依赖于 程序员自身的警惕性,这种警惕性来源于一种共同的约定,而不是编程语言所强制的。如果程 序员不够警惕—通常是因为他们太忙,这些机制就很容易被忽视
1.12 并发编程
在计算机编程中有一个基本概念,就是在同一时刻处理多个任务的思想。许多程序设计问 题都要求,程序能够停下正在做的工作,转而处理某个其他问题,然后再返回主进程。有许多 方法可以实现这个目的。最初,程序员们用所掌握的有关机器底层的知识来编写中断服务程序 主进程的挂起是通过硬件中断来触发的。尽管这么做可以解决问题,但是其难度太大,而且不 能移植,所以使得将程序移植到新型号的机器上时,既费时又费力 有时中断对于处理时间性强的任务是必需的,但是对于大量的其他问题,我们只是想把问 题切分成多个可独立运行的部分(任务),从而提高程序的响应能力。在程序中,这些彼此独立 运行的部分称之为线程,上述概念被称为“并发”。并发最常见的例子就是用户界面。
1.13 Java与 Internet
如果Java仅仅只是众多的程序设计语言中的一种,你可能就会问:为什么它如此重要?为 什么它促使计算机编程语言向前迈进了革命性的一步?如果从传统的程序设计观点看,问题的 答案似乎不太明显。尽管Java对于解决传统的单机程序设计问题非常有用,但同样重要的是 它解决了在万维网(WWW)上的程序设计问题。
1.14 总结
你知道过程型语言看起来像什么样子:数据定义和函数调用。想了解此类程序的含义,你 必须忙上一阵,需要通读函数调用和低层概念,以在脑海里建立一个模型。这正是我们在设计 过程式程序时,需要中间表示形式的原因。这些程序总是容易把人搞糊涂,因为它们使用的表 示术语更加面向计算机而不是你要解决的问题。 OOP和Java也许并不适合所有的人。重要的是要正确评估自己的需求,并决定Java是否能够 最好地满足这些需求,还是使用其他编程系统(包括你当前正在使用的)才是更好的选择。如 果知道自己的需求在可预见的未来会变得非常特殊化,并且Java可能不能满足你的具体限制 那么就应该去考察其他的选择(我特别推荐读者看看 Python,参见 www.Python. org)。即使最终 仍旧选择Java作为编程语言,至少也要理解还有哪些选项可供选择,并且对为什么选择这个方 向要有清楚的认识

浙公网安备 33010602011771号