《编程导论(Java)·前言》

来源:互联网 发布:mysql中删除unique约束 编辑:程序博客网 时间:2024/05/19 00:11

《编程导论(Java)·前言》

谢谢你翻阅这本书。
在2005年出版《Java程序设计》(宋中山,严千钧编著,清华大学出版社)时,有一个目标没有完成:以Java作为大学本科的入门级语言构建教学体系。虽然早早就着手进行相关研究,这么多年过去了,其难度超出我的预计。翻阅本书,你很容易发现它与传统的《Xxx程序设计》之类的书籍有太多的不同。这些不同,并非我刻意为之,而是这些年来本书的结构经过不断地重构而自然形成的。时间的积淀,对于本书的形成是至关重要的,虽然实在是缺乏效率。
《编程导论(Java)》的目标,是以Java语言作为教学载体,讲授(面向对象)程序设计/编程和算法的基本原理。它以对象优先的教学路线构建教学体系,并以柏拉图法则、Liskov原则和Parnas原则(PLP)为基石构建面向对象范式的逻辑体系。全书分成3部分:(1)面向对象编程基础,包括第1~6章;(2)Java API编程,包括第7~9章;(3)算法基础,包括第10、11章。
本书的读者主要为计算科学的相关专业3种类型的人士:本科一年级学生、教师和其他(现在和将来的软件开发人员,如高年级的学生、面试的考官等等)。


致大一学生


希望本书能够为同学们学习编程带来有趣的体验。学习之前,请做好如下准备:(1)最好有一台自己的计算机。学习本书的大多数章节,希望你同时运行随书代码库codes中相关的程序,还可能需要你去查阅Java标准库的文档。(2) 最好能够上网。网络上有数不尽的参考书、网络资源、开源的代码可供参考。由于网络的存在,我实在不愿意让Hello World级别的程序过多地占用本书的篇幅,各种基本语法和API的用法请参考随书代码库codes或附录中列举的网站。(3)有一颗安静而好奇的心。
学习面向对象编程,需要注意一个要点:面向对象的各概念之间联系得非常紧密,概念之间构成一个,在学习一个概念时,很难回避其他概念。也就是说,不能够采用阶梯型学习方法——全面掌握一个概念,在其基础上再掌握下一个概念。因而,在前面几章中会出现大量的重要概念,并在后面的章节中逐步深入地讨论。这是一种迭代式讲解和学习的方式,正如同我们从小到大还在揣摩的“公平”、“善良”等词汇,随着年龄的增长,对它们的认识不断地加深。
建议初学者按照书本的章节顺序去学习。在此过程中,你经常会遇到一些还没有“正式”讲解过的概念和代码语法。一方面是因为概念网的缘故;另一方面我通常会让你先感性认识、使用一些知识点,而后再介绍。我非常希望书本能够像网页,加上一些超级链接,可惜在纸质的书籍中难做到(你可以留意本书的网络资源)。通常情况下,你可以采用如下方式之一去应对:(1)依靠自己的直觉和常识,如对于许多操作符;(2)先快速翻阅后面的相关章节,特别是书中指明参照(类似超级链接)后面某个章节的时候;(3)先在书上打个问号,在后面学习到相关内容时,再回头进行归纳和总结;(4)当在演示例程中遇到若干非本书主题的知识,例如applet中涉及到一些HTML的代码、第7章中涉及的文件处理方面的代码等等,这时可以放弃研读或跳过非主题的代码,或者通过网络/其他书籍自学相关内容。总之,你要善于利用网络搜索引擎和身边的老师、同学等资源,学习小朋友喜欢问十万个为什么的精神。对于书中一笔带过的部分,可以不求甚解;对于书中详细讲解的内容,正如《菜根谭》中所言:“理路上事,毋惮其难而稍为退步,一退步便远隔千山”。
总体上,本书避免对Java的知识点加以全面的讲解,例如介绍基本类型时,书中列举了完整的基本类型,但是真正关注的,只有int、double、boolean、char等,如果需要用到其他的类型,你得自学。
对象技术的学习,你需要学习编程的抽象概念,需要培养编程的实际技能。两手都要硬是目标,实际学习过程中,学习理论知识时要防止沉迷于语言细节,过多的细节会分散注意力而导致对某些概念知其然而不知其所以然。编程的抽象概念,通常可以利用简单的例程形象地学习,反映在书籍中就是“讲解-代码-讲解”这样的编排。有些读者可能养成了没有代码的书就不读的习惯,但书籍篇幅所限,强烈地建议你(按照练习中要求)打开BlueJ,运行、调试、修改、补充各演示例程;编程技能的训练则需要掌握足够多的语言细节以便完成有意义的程序,而非仅仅学会编写Hello World级别的程序。掌握足够多的语言细节,一方面要通晓基于for等循环的算法设计与实现,一方面要学习Java API的使用。真实软件开发项目中的代码,则需要更为周全的考虑,例如统一的编程风格、完善的注释和文档、各种修饰符的选择、方法的参数检查、完整的异常处理和防御编程、有弹性的类层次设计等等,所有这些都需要在编程练习中逐步培养。
★First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack.——George Carrette。

若干文本约定


本书正文中使用了某些习惯表示法,均出于便于阅读和/或减少篇幅的需要。总之,它们非常直观,你并不需要仔细阅读下面的部分。之所以列出来,有备无患。
1.名词(英文),例如程序(program)、矩形(Rectangle)。术语后面的英文,便于你上网搜索英文资料,或从英文名词的日常用法中联想该术语的寓意;当要使用矩形时,给出JDK或随后例程中将使用的简单类名(首字母肯定是大写的)。
2.替代词,如程序设计/编程。正文中汉字间的除号/,表示彼此为可替代术语/近义词/补充。可以用“或、或者说、换言之、或称之为”等理解“/”。有时候写成:你(或许是环境)。
3.小括号()。正文中汉字间的(xxx),用于补充。省略xxx不会影响原句的含义。
4.方法,例如paint(Graphics)。通常正文中提及某个方法时,给出方法名及其参数类型,而一般不写方法形参的名字。使用频繁时,可能进一步省略参数类型如paint()。没有参数的方法如init(),不省略后面的括号。
5.类.方法,如Object.toString(Object)。通常正文中提及某个类的某个方法时,采用点表示“的”。请不要把它与源代码中类的静态方法混淆了。
6.交叉引用,如:本节介绍[1.2.1类体结构]提及的……。书中将交叉引用以[]括起来。交叉引用的目标主要为章节、例程和图表。
7.★的后面是重要言论/建议/格言……

代码片段和例程库codes


本书使用的所有源代码,全部放在文件夹codes (也是唯一的一级BlueJ项目)中,包括:
1.书中代码片段的完整代码。为了节约篇幅,很多时候,书中仅仅给出了值得关注的代码片段或示例代码,而代码片段需要依赖的代码则没有一一罗列;
2.练习中要求你阅读(精读或泛读)的代码;
3.运行本书的程序需要的支持代码。最典型的是tips.Print,为了节约篇幅,它被广泛采用。通过“import static tips.Print.*;”静态引入语句,源代码中pln(x)代替Java标准的输出语句System.out.println(x)或out.println(x)。
例程具有下列表格形式:
例程1-2不同种类的标识符
package semantics;
public class YQJ {
   //
}
题注包括(1)例程在对应章节中的编号(1-2表示第1章的第2个例程);(2)本例程的关注点。
书中代码的package xxx使你能够从文件夹codes中快速找到并打开源代码。
请注意:(各章节使用的)各个例程,并没有按照章节进行归类,而是按照主题内容分别安放在各个包中。因而,一个章节的例程因涉及多个主题,会使用多个包中的源代码;不同章节因迭代式讨论同一个主题,可能涉及到相同的包。
使用各个包时,请首先阅读其readMe.txt文件。如果需要在readMe中添加更多的信息,请打开BlueJ后,在该环境中修改。

 

致教师


《编程导论(Java)》适合作为软件工程、计算机科学与技术、网络工程、电子商务和信息管理与信息系统等专业的大学本科入门语言教学的教程。
在撰写本书的过程中,参阅了美国大量的关于课程体系、Java语言教学的文献,经过无数次的演化,最终形成本书目前的结构。本书的写作主要考虑如下几点:

  1. 入门语言的选择——Java。国外80%以上的大学、甚至高中使用Java作为第一门语言,而我国大量学校仍旧在使用C语言。Java是面向对象概念的简单而完美的体现,因而非常适合作为入门语言;而先学习C语言,会导致学生在学习面向对象编程时遭受痛苦的“范式迁移”,这已成为教育界定论。当然,Java教学也有诸多困难,ACM Java Task Force研究了相关问题,并开发了acm.jar作为教学辅助工具包,其主席Eric Roberts出版了相应的教程《The Art and Science of Java》。本书批判性地吸收了Java特别工作组的观点,例如静态成员并非不合时宜;同时对于第3方包的使用,我持谨慎态度。
  2. 对象优先教学策略。对象优先的第一层含义是入门语言的选择上,用面向对象的语言替代过程语言;第二层含义,则是先介绍类的知识而非先讲控制结构,这一点在教育界存在巨大分歧。对象优先困难,(1)有人认为:在学习控制结构之前的例程没有实际意义。事实上,介绍控制结构后,在讲授面向对象知识时使用的例程,通常也没有实际意义。正如[5.1.2针对LinearList编程]中体现的,“实际意义”并非指有趣或有用的代码,这不是面向对象要解决的问题。(2)有人说:不能用过程式编程写代码的人就不能够学习面向对象编程。这是一种混淆了功能抽象与过程式编程的误解,更严重的错误是,他将面向对象编程作为实现的特殊工具而非程序组织的一个方式。(3) 对象优先的困难,通常是人们在学习对象技术时,缺乏明确的起点和清晰的学习思路,这一点在[5.PLP]中说明。当然,适当的学习工具非常重要,BlueJ就是极好的Java开发环境,《实用Java教程:基于BlueJ的对象优先方法(第3版)》可以作为上机实验教程,我建议至少让所有的学生在BlueJ的官方网站下载该书的英文电子版。本书借鉴了该书的迭代教学方法、不求面面俱到的思路。但是,对他们的“项目驱动”的方式持保留意见(如果是通常意义的项目而非BlueJ菜单上的project),在入门语言教学中引入项目案例,难以保证需求分析和系统设计到位。如果仅仅让学生阅读编写好的项目代码,又如果这些代码按照真实软件开发项目的要求来编写,将引入太多的额外考虑。本书中有若干案例但不称之为项目。对于项目,我倾向于通过课程设计,提供一个将全真项目加以简化而形成的典型案例让学生模仿,这就要求教师拥有较丰富的实践/开发经验。
  3. 语言的整合。本书讲授编程时,强调with Java而非in Java。需要告诉学生:“你们应该掌握这些知识,而它们在Java中是如此这般实现的”。我国大学的课程体系中,通常开设了C、C++和Java课程。这种“进课堂、保学时”的简单加法式的课程大纲和计划所安排的C、C++和Java教学,一定程度上顾及了语言的广度,但是缺乏对语言共性的整合。ACM/IEEE联合工作室制订的Computing Curricula 2005、Software Engineering 2004等,将知识体系划分为若干知识领域,细分为知识单元(请参考[0.1.4计算机科学]和附录B),国内也有相关的东西。本书在整体内容上,覆盖CC2001的CS111O的要求,同时本书的某些章节在附录B中没有列出,它们是为了衔接面向对象设计、需求分析与设计等课程而准备的。
  4. 加深理论。课堂教学以原理、概念及思路的讲解为主,教师应成为学生的知识索引。传统的以语法为核心的教学,并非真正的理论课而是某些文科课程的教学方式。面向对象的封装、继承、动态绑定(方法改写)、多态等知识,在编程语言教学中并没有太多的理论含义(这种课程不涉及编程语言设计和形式化的内容),本书强调按照人们熟悉的、习惯的思维方式,去“构造和组织”程序,希望学生掌握编程范式、接口与实现分离和抽象等概念,掌握类层次(包括Is-A关系 、里氏替换原则)、抽象的依赖(包括开放封闭原则、针对接口编程),合成复用原则等。书中并不刻意回避设计模式,我建议让学生至少阅读《设计模式》的1.6节,或许包括3.3、4.1、5.4、5.7节。
  5. 面向对象范式的基石:PLP。不同于基于图灵机的过程/命令编程范式和基于λ运算的函数编程范式,面向对象编程范式没有直接的、源于计算科学的理论模型。它之所以被称为“新”范式,仅仅因为它采用了完全不同的看待程序的视角。本书独创性地将柏拉图(Plato)原则、里氏(Liskov)替换原则和Parnas原则(合称PLP、有学生问PLP是不是漂流瓶)作为面向对象编程范式的基石。(1)面向对象范式的第一原则,我称之为柏拉图法则,它是对象技术的观念范式和心理范式的根源,对象技术是通过颠倒的理念世界而模拟唯物的真实世界。(2)里氏替换原则是正确设计类层次的指导原则,也是对象技术的逻辑体系的基石,由该原则很容易引申出继承性、多态性等对象技术的重要特性和语言机制。封装、继承、多态在教学中要淡化处理。例如多态,有人将重载(overload)、改写(override)、多态变量和泛型归结于同一个术语之下,好像孔乙己说“多态这个字有4种写法”一样,除了凸显多态这一术语比较多态(甚至变态)外,并没有理论意义和教学意义,因而本书使用了一个标题——“2.1.2啊,我看见了多态”,使多态术语具有简洁的语意。(3)本书将Parnas原则即接口与实现的分离作为对象技术的基本原则,不仅仅因为Parnas原则是软件工程中最重要的原则,也因为该原则在对象技术中的一系列的推广和应用,Parnas原则是功能抽象的核心,也是数据抽象、封装的底层依据。
  6. 书本偏向理论,而练习和随书代码库偏向技能训练。技能训练方面,课堂案例分析和上机实验之外,建议教师补充若干简化的全真项目,如小型信息系统(涉及GUI、数据库)、多媒体程序、网络程序供学生阅读。
  7. 其他。链表放在数组前面介绍,是因为我很久前看过一篇论文;本书提及了许多的语言,我比较熟悉C、C++、C#、Java ,有所了解的有FORTRAN、PASCAL、Groovy、Scala,其他语言连编译器都没有下载过。教师在处理语言的语法差异时,可以为学生提供更多的补充;教学学时不够时,引言、位运算以及目录中带*的章节,教师可灵活地安排学生自学。

 

致其他读者


基础很重要。《编程导论(Java)》可以作为大三、大四准备找工作的同学全面回顾面向对象概念和算法基础的参考资料。你应该能够在一个月的时间内拿下《编程导论(Java)》的全部内容,然后复习Java API编程(例如流、集合框架、多线程等)和数据结构和算法的其他内容以应对Java程序员的面试。
在我国当前的教学模式、课程体系之下,有大三学生反映《编程导论(Java)》包含很多他们不熟悉甚至没有听说过的知识点,因而本书是你补漏的系统资料。对于面试的考官和学生,希望《编程导论(Java)》能够提供了一个基本的评估大纲。
对于软件公司的程序员们,本书是你全面梳理和回顾对象技术知识的良好参考资料,也可以作为软件公司内部培训的教材和参考书。IT培训机构可以灵活地调整教学计划,本书是讲授对象技术课程的良好选择。

 

网络资源


本书的例程库codes和教学PPT,请到清华大学出版社网站上下载。
广大读者对本书的批评、指正、意见和建议,可以通过清华大学出版社写信给我,也可以发送电子邮件到:yqj2065@qq.com。
在学习本书时遇到困惑,请不要发送电子邮件要求我解答,请到CSDN的论坛中求教,并在我的博客对应章节处给一个链接。在CSDN上我准备了有一个专门的网页介绍本书的最新消息、各章节讨论题和勘误表更新(的链接):
http://blog.csdn.net/yqj2065/article/details/8274282

 

致谢


特别感谢我的朋友和同事帖军老师为本书的结构顺序、知识点的取舍提供了许多宝贵的建议,我经常与帖军老师探讨教学方法、技巧和课程体系,他的许多观点和想法给我以启发。感谢学生严求知、刘蒙蒙、方丹丹、程品、吴浩和王小荣,冯忠双,刘江,杨露,蓝招有,张学敏等,作为本书的首批读者,不仅为本书找出了上百处文字、格式上的问题,还从学生的角度介绍了他们的学习体会。
感谢清华大学出版社的计算机与信息分社事业部主任魏江江,从本书投稿之日起,魏江江主任为本书的起名、办理出版手续、出版合同、安排编辑加工等付出大量心血;并就书籍的写作原则(要适合教学)、体例和结构提供了许多宝贵的建议,期间我们互通的电子邮件有几十封,感谢他的合作、耐心和付出。感谢薛阳编辑对本书做了极为细致的校审,她指出了大量文字、格式、措辞和表达方式上的缺陷。感谢清华大学出版社为本书出版而作出努力的所有人员。
最后,谢谢读者选择这本书。