<code>2018年1月7日15:45:58</code>java
做爲學習Java語言的經典之做《Java編程思想》,經常被人提起。雖然這本書出版十年有餘,可是內容仍是很給力的。不少人說這本書不是很適合初學者,我也是這麼以爲(拙見),你最好熟悉一門高級語言,這樣比較容易看懂。這本書也許不如國內一些教材那樣,知識點精煉、簡潔,可是大神Bruce Eckel更多講的是Java編程思想,深刻淺出。曾在某文章中看到過有人把這本書看過十遍,每看一遍都有不一樣的收穫,但願多年後我也有這樣的收穫。程序員
做爲母校的教材(英文版),當我再次捧起這本書(中文版)的時候,我已再也不是學生,以此係列文章記錄本身的感悟與收穫。面試
ps:英文原版《Thinking in Java》,在畢業的時候,以四毛一斤的高價賣給了收二手書的,想當初花了一百多人民幣買回來,如今連尾數都收不回。編程
總結:正如書上說的數組
本章將向讀者介紹包括開發方法概述在內的OOP的基本概念。 本章介紹的是背景性的和補充性的材料。安全
第一章主要是敘述了面向對象的基本概念,和全書所講述的內容的提綱,包括java語言三大特性:封裝、繼承、多態,容器,泛型,對象的生命週期,異常,併發,以及JavaWeb的相關知識。併發
全部編程語言都提供抽象機制。能夠認爲,人們可以解決的問題的複雜性直接取決於抽象的類型和質量。iphone
編程語言的由來,其實和人類語言的由來同樣的,抽象出來的啊。我說「蘋果」,那個圓圓的、紅紅的、甜的東西就出如今你腦海中,你要說是青色的,你要說是iphone,那我也沒辦法。可是「蘋果」就是從這些東西抽象出來的文字形式,它是從一個砸過牛頓的圓圓的、紅紅的、甜的東西抽象出來的。可是若是沒有「蘋果」這個詞,咱們是否是要說描述很長很長或者隨身帶一個「蘋果」。計算機只認識0和1。編程語言
彙編語言是對底層機器的輕微抽象。接着出現的許多所謂「命令式」語言(如FORTAN、BASIC、C等)都是對彙編語言的抽象。函數
Java也是從底層語言抽象出來的,站在巨人的肩膀上。
面向對象的五個基本特性(Alan Kay總結):
1)萬物皆爲對象。 2)程序是對象的集合,它們經過發送消息來通知彼此所要作的。 3)每一個對象都有本身的由其餘對象所構成的存儲。 4)每一個對象都擁有其類型。 5)某一特定類型的全部對象均可以接收一樣的消息。
Booch對對象提出了一個更加簡潔的描述:
對象具備狀態、行爲和標識。
接口肯定了對某一特定對象所能發出的<i>請求</i>。可是,在程序中必須有知足這些請求的代碼。這個代碼與隱藏的數據以及構成了<i>實現</i>。
訪問控制(Access Control)的第一個存在緣由就是讓客戶端程序員沒法觸及他們不該該觸及的部分——這是部分對數據類型的內部操做來講是必需的,但並非用戶解決特定問題所需的接口的一部分。 訪問控制的第二個存在緣由就是容許庫設計者能夠改變類內部的工做方式而不用擔憂會影響到客戶端程序員。 Java用三個關鍵字在類的內部設定邊界:public、private、protected.
最簡單地複用某個類的方式就是直接使用該類的一個對象,此外也能夠<i>將那個類的一個對象置於某個新的類中</i>。咱們稱其爲「建立一個成員對象」。 由於是在使用現有的類,因此這種概念被稱爲組合(composition),若是組合是動態發生的,那麼它一般被稱爲聚合(aggregation)。 組合常常被視爲「has-a」(擁有)關係。
若是子類繼承父類,沒有添加新的方法,是is-a關係。
若是子類繼承父類,添加新的方法,是is-like-a關係。
多態出現的緣由:
在處理類型的層次結構時,常常想把一個對象不看成它所屬的特定類型來對待,而是將其看成其基類的對象來對待。
實現多態意味着:
編譯器不可能產生傳統意義上的函數調用。
一個非面向對象的編譯器產生的函數調用會引發所謂的前期綁定,意味着編譯器將產生對一個具體函數名字的調用,而運行是將這個調用解析到將要被執行的代碼的絕對地址。然而在OOP中,程序直到運行是纔可以肯定代碼的地址。
爲了解決這個問題,面向對象程序設計語言使用了<i>後期綁定</i>的概念。 爲了執行後期綁定,Java使用一小段的代碼來替代絕對地址調用。這段代碼使用在對象中存儲的信息來計算方法體。這樣,根據這一小段代碼的內容,每一個對象均可以據用不一樣的行爲表現。 在Java中,動態綁定是默認行爲,不須要添加額外的關鍵字來實現多態。
在Java中,<strong>全部的類最終都繼承自單一的基類object</strong>。
好處:
在單根繼承結構中的全部對象都具備一個共用接口,因此它們歸根到底都是相同的基本類型。 單根繼承結構保證全部對象都具有某些功能。 單根繼承結構使垃圾回收器的實現變得容易得多。
容器:
建立另外一種對象類型。這種新的對象類型特有對其餘對象的引用。
在Java中,具備知足不一樣須要的各類類型的容器:
List(用於存儲序列), Map(也被成爲關聯數組, 用來創建對象之間的關聯),set(每種對象類型只持有一個),以及以及租入隊列、樹、堆棧等更多的構件。
須要多種類型的容器的緣由:
第一,不一樣的容器提供了不一樣類型的接口和外部行爲。 第二,不一樣的容器對於某些操做具備不一樣的效率。 咱們能夠根據不一樣的需求選擇不一樣的容器。面試的時候最多問到的問題之一應該有這個吧,關於ArrayList和LinkedList的區別。 在ArrayList中,<i>隨機訪問元素</i>是一個花費固定時間的操做;可是,對LinkedList來講,隨機選取元素須要在列表中移動,這種代價是高昂的,訪問越靠近表尾的元素,花費的時間越長。 而另外一方面,若是想在序列中間<i>插入</i>一個元素,LinkedList的開銷卻比ArrayList要小。
知道它們的底層構造,理解起來就不是那難了,ArrayList存放對象的空間在物理上是連續的,底層是Array(數組),LinkedList存在對象的空間在物理上不必定是連續的。
這比如這裏有一羣孩子在操場上體育課,一開始孩子們要排隊報個數,這樣老師說3號孩子出來,就能夠立刻找到,這是<i>隨機訪問元素</i>。接着有一個孩子遲到了,而後這個孩子<i>插入</i>到隊伍中,就須要挪一個位置給他,若是他在4號位置上,那麼這樣在4號後的孩子們都要挪。報完數就自由活動了,這時候又來了一個遲到的孩子X,老師心情正好,由於男友說今晚一塊兒去吃大餐,就不責備孩子X了,說去玩吧,這個孩子就<i>插入</i>在操場上玩耍的大部隊裏了。接着校長過來講要找X孩子,假設每一個孩子只認識一個孩子,這樣老師在操場邊拉了一個孩子A說,我要找孩子X,孩子A只能告訴他認識的孩子B,繼而B告訴C,如此循環,直到找到X,這就是<i>隨機訪問元素</i>。
這是個小故事,前者是ArrayList,後者是LinkedList。
在Java SE5出現以前,容器存儲的對象都只具備Java中的通用類型:Object。 單根繼承結構意味着全部東西都是Object類型,因此能夠存儲Object的容器能夠存儲任何東西。 把將派生類看作它的基類的過程稱爲<i>向上轉型</i>。
向上轉型成Object是安全的,若是從Object向下轉型爲具體類型,除非確切知道所要處理的對象的類型,不然向下轉型是不安全的。
參數化類型機制的緣由:要建立知道本身所保存的對象的類型的容器,不須要向下轉型以及消除犯錯誤的可能。
在Java中,參數化類型稱爲<i>泛型</i>。
在使用對象時,最關鍵的問題之一即是它們的生成和銷燬方式。 每一個對象爲了生存都須要資源,尤爲是內存。
C++認爲效率控制是最重要的議題:
爲了追求最大的執行速度,對象的存儲空間和聲明週期能夠在編寫程序時肯定,這能夠經過將對象置於堆棧(它們有時被稱爲自動變量(automatic variable)或限域變量(scoped variable))或靜態存儲區來實現。
Java採用動態內存分配方式。
在稱爲堆(heap)的內存池中動態地建立對象。 由於存儲空間是在運行是被動態管理的,因此須要大量的時間在堆中分配存儲空間,可能要遠遠大於在堆棧中建立存儲空間的時間。 動態方式有這樣一個通常性的邏輯假設:對象趨向於變得複雜,因此查找和釋放存儲空間的開銷不會對對象的建立形成重大沖擊。
這裏有一個翻譯的坑,之前我不知道:堆棧是棧。
Java對象生命週期:
若是是在堆上建立對象,編譯器就會對它的生命週期一無所知。 Java提供了被稱爲「垃圾回收器」的機制,它能夠自動發現對象什麼時候再也不被使用,並繼而銷燬它。
開始於new,終結於GC。
垃圾回收器:
垃圾回收器提供了更高層的保障,能夠避免暗藏的內存泄露問題。 Java垃圾回收器被設計用來處理內存釋放問題(儘管它不包括清理對象的其餘方面)。 垃圾回收器「知道」對象什麼時候再也不被使用,並自動釋放對象佔用的內存。這一點同全部對象都是繼承自單根基類Object以及只能以一種方式建立對象(在堆上建立)這兩個特性結合起來。
異常提供了一種從錯誤情況進行可靠恢復的途徑。
在計算機編程中有一個基本概念,就是在同一時刻處理多個任務的思想。
JavaWeb相關敘述,略過。
過程式語言:
數據定義和函數調用。
Java程序:
用來表示問題空間概念的對象(而不是有關計算機表示方式的相關內容),以及發送給這些對象的用來表示在此看空間內的行爲的消息。
最後的最後,做者說,這章能夠跳過。我?!