天天看點

《程式設計導論(Java)·前言》

《程式設計導論(Java)·前言》

《程式設計導論(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,請到清華大學出版社網站上下載下傳。

廣大讀者對本書的批評、指正、意見和建議,可以通過清華大學出版社寫信給我,也可以發送電子郵件到:[email protected]。

在學習本書時遇到困惑,請不要發送電子郵件要求我解答,請到CSDN的論壇中求教,并在我的部落格對應章節處給一個連結。在CSDN上我準備了有一個專門的網頁介紹本書的最新消息、各章節讨論題和勘誤表更新(的連結):

http://blog.csdn.net/yqj2065/article/details/8274282

緻謝

特别感謝我的朋友和同僚帖軍老師為本書的結構順序、知識點的取舍提供了許多寶貴的建議,我經常與帖軍老師探讨教學方法、技巧和課程體系,他的許多觀點和想法給我以啟發。感謝學生嚴求知、劉蒙蒙、方丹丹、程品、吳浩和王小榮,馮忠雙,劉江,楊露,藍招有,張學敏等,作為本書的首批讀者,不僅為本書找出了上百處文字、格式上的問題,還從學生的角度介紹了他們的學習體會。

感謝清華大學出版社的計算機與資訊分社事業部主任魏江江,從本書投稿之日起,魏江江主任為本書的起名、辦理出版手續、出版合同、安排編輯加工等付出大量心血;并就書籍的寫作原則(要适合教學)、體例和結構提供了許多寶貴的建議,期間我們互通的電子郵件有幾十封,感謝他的合作、耐心和付出。感謝薛陽編輯對本書做了極為細緻的校審,她指出了大量文字、格式、措辭和表達方式上的缺陷。感謝清華大學出版社為本書出版而作出努力的所有人員。

最後,謝謝讀者選擇這本書。