提交 5bc9ed32 编写于 作者: W wizardforcel

chs

上级 43c968f2
此差异已折叠。
......@@ -3,7 +3,7 @@
利用对象,可将一个程序分割成相互独立的区域。我们通常也需要将一个程序转换成多个独立运行的子任务。
象这样的每个子任务都叫作一个“线程”(Thread)。编写程序时,可将每个线程都想象成独立运行,而且都有自己的专用CPU。一些基础机制实际会为我们自动分割CPU的时间。我们通常不必关心这些细节问题,所以多线程的代码编写是相当简便的。
象这样的每个子任务都叫作一个“线程”(`Thread`)。编写程序时,可将每个线程都想象成独立运行,而且都有自己的专用CPU。一些基础机制实际会为我们自动分割CPU的时间。我们通常不必关心这些细节问题,所以多线程的代码编写是相当简便的。
这时理解一些定义对以后的学习狠有帮助。“进程”是指一种“自包容”的运行程序,有自己的地址空间。“多任务”操作系统能同时运行多个进程(程序)——但实际是由于CPU分时机制的作用,使每个进程都能循环获得自己的CPU时间片。但由于轮换速度非常快,使得所有程序好象是在“同时”运行一样。“线程”是进程内部单一的一个顺序控制流。因此,一个进程可能容纳了多个同时执行的线程。
......
......@@ -2,7 +2,7 @@
本章要向大家介绍重要但却并不是那么传统的“模式”(Pattern)程序设计方法。
在向面向对象程序设计的演化过程中,或许最重要的一步就是“设计模式”(Design Pattern)的问世。它在由Gamma,Helm和Johnson编著的《设计模式》一书中被定义成一个“里程碑”(该书由Addison-Wesley于1995年出版,注释①)。那本书列出了解决这个问题的23种不同的方法。在本章中,我们准备伴随几个例子揭示出设计模式的基本概念。这或许能激起您阅读《Design Pattern》一书的欲望。事实上,那本书现在已成为几乎所有OOP程序员都必备的参考书。
在向面向对象程序设计的演化过程中,或许最重要的一步就是“设计模式”(Design Pattern)的问世。它在由Gamma,Helm和Johnson编著的《设计模式》一书中被定义成一个“里程碑”(该书由Addison-Wesley于1995年出版,注释①)。那本书列出了解决这个问题的23种不同的方法。在本章中,我们准备伴随几个例子揭示出设计模式的基本概念。这或许能激起您阅读《设计模式》一书的欲望。事实上,那本书现在已成为几乎所有OOP程序员都必备的参考书。
①:但警告大家:书中的例子是用C++写的。
......
......@@ -7,6 +7,6 @@
为达到这个目的,需遵守一定的约定或规则。例如,库程序员在修改库内的一个类时,必须保证不删除已有的方法,因为那样做会造成客户程序员代码出现断点。然而,相反的情况却是令人痛苦的。对于一个数据成员,库的创建者怎样才能知道哪些数据成员已受到客户程序员的访问呢?若方法属于某个类唯一的一部分,而且并不一定由客户程序员直接使用,那么这种痛苦的情况同样是真实的。如果库的创建者想删除一种旧有的实现方案,并置入新代码,此时又该怎么办呢?对那些成员进行的任何改动都可能中断客户程序员的代码。所以库创建者处在一个尴尬的境地,似乎根本动弹不得。
为解决这个问题,Java推出了“访问指示符”的概念,允许库创建者声明哪些东西是客户程序员可以使用的,哪些是不可使用的。这种访问控制的级别在“最大访问”和“最小访问”的范围之间,分别包括:public,“友好的”(无关键字),protected以及private。根据前一段的描述,大家或许已总结出作为一名库设计者,应将所有东西都尽可能保持为“private”(私有),并只展示出那些想让客户程序员使用的方法。这种思路是完全正确的,尽管它有点儿违背那些用其他语言(特别是C)编程的人的直觉,那些人习惯于在没有任何限制的情况下访问所有东西。到这一章结束时,大家应该可以深刻体会到Java访问控制的价值。
为解决这个问题,Java推出了“访问指示符”的概念,允许库创建者声明哪些东西是客户程序员可以使用的,哪些是不可使用的。这种访问控制的级别在“最大访问”和“最小访问”的范围之间,分别包括:`public`,“友好的”(无关键字),`protected`以及`private`。根据前一段的描述,大家或许已总结出作为一名库设计者,应将所有东西都尽可能保持为`private`(私有),并只展示出那些想让客户程序员使用的方法。这种思路是完全正确的,尽管它有点儿违背那些用其他语言(特别是C)编程的人的直觉,那些人习惯于在没有任何限制的情况下访问所有东西。到这一章结束时,大家应该可以深刻体会到Java访问控制的价值。
然而,组件库以及控制谁能访问那个库的组件的概念现在仍不是完整的。仍存在这样一个问题:如何将组件绑定到单独一个统一的库单元里。这是通过Java的package(打包)关键字来实现的,而且访问指示符要受到类在相同的包还是在不同的包里的影响。所以在本章的开头,大家首先要学习库组件如何置入包里。这样才能理解访问指示符的完整含义。
然而,组件库以及控制谁能访问那个库的组件的概念现在仍不是完整的。仍存在这样一个问题:如何将组件绑定到单独一个统一的库单元里。这是通过Java的`package`(打包)关键字来实现的,而且访问指示符要受到类在相同的包还是在不同的包里的影响。所以在本章的开头,大家首先要学习库组件如何置入包里。这样才能理解访问指示符的完整含义。
......@@ -10,4 +10,3 @@
第二种方法则显得稍微有些技巧。它创建一个新类,将其作为现有类的一个“类型”。我们可以原样采取现有类的形式,并在其中加入新代码,同时不会对现有的类产生影响。这种魔术般的行为叫作“继承”(Inheritance),涉及的大多数工作都是由编译器完成的。对于面向对象的程序设计,“继承”是最重要的基础概念之一。它对我们下一章要讲述的内容会产生一些额外的影响。
对于合成与继承这两种方法,大多数语法和行为都是类似的(因为它们都要根据现有的类型生成新类型)。在本章,我们将深入学习这些代码复用或者重复使用的机制。
......@@ -5,6 +5,6 @@
“多态性”(Polymorphism)从另一个角度将接口从具体的实现细节中分离出来,亦即实现了“是什么”与“怎样做”两个模块的分离。利用多态性的概念,代码的组织以及可读性均能获得改善。此外,还能创建“易于扩展”的程序。无论在项目的创建过程中,还是在需要加入新特性的时候,它们都可以方便地“成长”。
通过合并各种特征与行为,封装技术可创建出新的数据类型。通过对具体实现细节的隐藏,可将接口与实现细节分离,使所有细节成为“private”(私有)。这种组织方式使那些有程序化编程背景人感觉颇为舒适。但多态性却涉及对“类型”的分解。通过上一章的学习,大家已知道通过继承可将一个对象当作它自己的类型或者它自己的基类型对待。这种能力是十分重要的,因为多个类型(从相同的基类型中派生出来)可被当作同一种类型对待。而且只需一段代码,即可对所有不同的类型进行同样的处理。利用具有多态性的方法调用,一种类型可将自己与另一种相似的类型区分开,只要它们都是从相同的基类型中派生出来的。这种区分是通过各种方法在行为上的差异实现的,可通过基类实现对那些方法的调用。
通过合并各种特征与行为,封装技术可创建出新的数据类型。通过对具体实现细节的隐藏,可将接口与实现细节分离,使所有细节成为`private`(私有)。这种组织方式使那些有程序化编程背景人感觉颇为舒适。但多态性却涉及对“类型”的分解。通过上一章的学习,大家已知道通过继承可将一个对象当作它自己的类型或者它自己的基类型对待。这种能力是十分重要的,因为多个类型(从相同的基类型中派生出来)可被当作同一种类型对待。而且只需一段代码,即可对所有不同的类型进行同样的处理。利用具有多态性的方法调用,一种类型可将自己与另一种相似的类型区分开,只要它们都是从相同的基类型中派生出来的。这种区分是通过各种方法在行为上的差异实现的,可通过基类实现对那些方法的调用。
在这一章中,大家要由浅入深地学习有关多态性的问题(也叫作动态绑定、推迟绑定或者运行期绑定)。同时举一些简单的例子,其中所有无关的部分都已剥除,只保留与多态性有关的代码。
......@@ -6,11 +6,11 @@ Java的基本原理就是“形式错误的代码不会运行”。
在C++和其他早期语言中,可通过几种手续来达到这个目的。而且它们通常是作为一种规定建立起来的,而非作为程序设计语言的一部分。典型地,我们需要返回一个值或设置一个标志(位),接收者会检查这些值或标志,判断具体发生了什么事情。然而,随着时间的流逝,终于发现这种做法会助长那些使用一个库的程序员的麻痹情绪。他们往往会这样想:“是的,错误可能会在其他人的代码中出现,但不会在我的代码中”。这样的后果便是他们一般不检查是否出现了错误(有时出错条件确实显得太愚蠢,不值得检验;注释①)。另一方面,若每次调用一个方法时都进行全面、细致的错误检查,那么代码的可读性也可能大幅度降低。由于程序员可能仍然在用这些语言维护自己的系统,所以他们应该对此有着深刻的体会:若按这种方式控制错误,那么在创建大型、健壮、易于维护的程序时,肯定会遇到不小的阻挠。
①:C程序员研究一下printf()的返回值便知端详。
①:C程序员研究一下`printf()`的返回值便知端详。
解决的方法是在错误控制中排除所有偶然性,强制格式的正确。这种方法实际已有很长的历史,因为早在60年代便在操作系统里采用了“异常控制”手段;甚至可以追溯到BASIC语言的on error goto语句。但C++的异常控制建立在Ada的基础上,而Java又主要建立在C++的基础上(尽管它看起来更象Object Pascal)。
解决的方法是在错误控制中排除所有偶然性,强制格式的正确。这种方法实际已有很长的历史,因为早在60年代便在操作系统里采用了“异常控制”手段;甚至可以追溯到BASIC语言的on error `goto`语句。但C++的异常控制建立在Ada的基础上,而Java又主要建立在C++的基础上(尽管它看起来更象Object Pascal)。
“异常”(Exception)这个词表达的是一种“例外”情况,亦即正常情况之外的一种“异常”。在问题发生的时候,我们可能不知具体该如何解决,但肯定知道已不能不顾一切地继续下去。此时,必须坚决地停下来,并由某人、某地指出发生了什么事情,以及该采取何种对策。但为了真正解决问题,当地可能并没有足够多的信息。因此,我们需要将其移交给更级的负责人,令其作出正确的决定(类似一个命令链)。
“异常”(`Exception`)这个词表达的是一种“例外”情况,亦即正常情况之外的一种“异常”。在问题发生的时候,我们可能不知具体该如何解决,但肯定知道已不能不顾一切地继续下去。此时,必须坚决地停下来,并由某人、某地指出发生了什么事情,以及该采取何种对策。但为了真正解决问题,当地可能并没有足够多的信息。因此,我们需要将其移交给更级的负责人,令其作出正确的决定(类似一个命令链)。
异常机制的另一项好处就是能够简化错误控制代码。我们再也不用检查一个特定的错误,然后在程序的多处地方对其进行控制。此外,也不需要在方法调用的时候检查错误(因为保证有人能捕获这里的错误)。我们只需要在一个地方处理问题:“异常控制模块”或者“异常控制器”。这样可有效减少代码量,并将那些用于描述具体操作的代码与专门纠正错误的代码分隔开。一般情况下,用于读取、写入以及调试的代码会变得更富有条理。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册