今天要分享的是關於《Head First Java》
這本書的讀後感,這本書有點小厚差很少有七百頁左右,因此我花了幾乎整個國慶的時間去閱讀,學習。讀完以後發現,受益頗多。正如書名所說的,它是一本重視大腦的學習指南。不管你是Java
開發工程師,仍是android
開發工程師,這本書都是良師益友。下面讓咱們一塊兒看看,我會以零碎的列表方式呈現,並以通俗的方式講解那些你迷糊不清的細節?java
[1]
不管你的程序有多大(也能夠說無論有多少個類),必定都會有一個main()
來做爲程序的起點。[2]
System.out.print
與System.out.printIn
的區別,不少人其實一直沒注意,快捷鍵用習慣了吧,?。都是在控制檯打印結果,區別就是:前者打印後不換行,後者(帶In
的)打印後自動會換行。[3]
寫代碼若是你總是隻會寫一個個不相關類組合在一塊兒,來完成功能,也許你會缺失設計的靈性,有種設計手法叫「繼承「你們都知道,子類會繼承父類的方法,也就是說,子類會自動獲取父類的功能(提升了類的重用性)注:當父類被final
修飾的時候,它沒法當爹,它是沒法被繼承的(爲何要用這個來修飾類,爲了保持類的嚴謹性,避免被篡改,使用的場景:String
類就是最好的例子)。當父類的方法被final
修飾的時候,它是能夠被子類繼承使用,可是請注意你是沒法重寫(Override
) 該方法。[4]
類跟對象的關係:類不是對象,倒是用來建立對象的模型,也能夠說類是對象的藍圖。對象是已知的事物,對象會執行的動做。對象自己已知的事物被稱爲:實例變量(instance variable
)俗稱屬性
。對象能夠執行的動做稱爲:方法(methods
)。[5]
真正的面向對象的Java應用程序只會讓對象與對象交互,因此請多多以對象的角度考慮問題,編碼。[6]
變量根據做用域分爲:全局變量,局部變量。根據類型分類:primitive
主數據類型和引用。主數據類型主要有:boolean char byte short int long float double
。注:編譯器不容許將大杯的內容放到小杯中,可是反過來能夠。[7]
關於引用我以爲有必要拿出來特別講講:如Dog d = new Dog();
事實上沒有對象變量這樣的東西存在,只有引用(reference
)到對象的變量,對象引用變量保存的是存取對象的方法,它並非對象的容器,而是相似指向對象的指針(你能夠這麼理解,它就是這個對象的遙控器
,而不是這個對象自己)。[8]
不管被聲明來承載的是primitive
主數據類型或對象引用,數組永遠都是對象。[9]
對象有狀態和行爲兩種屬性,狀態影響行爲,行爲影響狀態。你們能夠好好理解這句話。[10]
在聲明方法的時候,方法的參數叫作形參,如:void bark(int numOfBarks)
,numOfBarks
就是形參。當咱們調用方法的時候咱們會傳入實參,:Dog d = new Dog();d.bark(3);
,這裏的3
就是實參。注:對於傳入的實參若是是主數據類型的時候,不管方法內部執行什麼,都不會改變這個實參,傳入的時候的值。可是傳入的實參若是是引用的時候,就會改變這個對象,特別注意引用是這個對象的遙控器,固然能夠改掉這個對象的東西。[11]
方法有聲明返回的類型,void
這表明沒有返回任何東西,其餘的聲明類型的話,說好了要返回,就是要返回相應的數據結果。[12]
傳入與傳出方法的值類型能夠隱含地放大或是明確地縮小。這句話你們也好好思考一下哈。[13]
封裝的基本原則:將你的實例變量標記爲私有的,並提供公用的getter
與setter
來控制存取動做。封裝的意義:能夠保護你的對象狀態不會隨意的被亂修改,若是要修改你的對象的狀態,他必需要調用你的setter
方法,在這個setter
方法中,你能夠添加你想要的數據要求約束條件,來保證你的狀態的修改值是合法。[14]
實例變量與局部變量之間的差異:實例變量能夠不用初始化就有默認值,局部變量沒有默認值!若是在變量被初始化前就要使用的話,編譯器會顯示錯誤![15]
==
跟equals()
的區別:哈哈這也是老問題了,使用==
來比較primitive
主數據類型,或者判斷兩個引用是否引用同一個對象。使用equals()
來判斷兩個對象是否在乎義上相等。(什麼?很差懂?一般的用法就是若是比較字符串就用equals
,若是比較數字是否是相等就用==
。?)[16]
咱們在設計編寫類的時候,最好遵循下面的順序:找出類應該作的事情,列出實例變量和方法,編寫方法的僞碼,編寫方法的測試用程序,實現類,測試方法,除錯或從新設計,完成。也就是三個大步驟:僞碼,測試碼,真實碼。[17]
關於for
循環分爲兩種:第一種基本(非增強版)的for
循環,如:for(int i=0;i<100;i++){};
第二種(增強版)的for循環,如:for(String name :nameArray){};
注:請多寫寫不同的好代碼,切莫一個挫代碼能用就行的心態,處處寫,這會讓你的技術停留不前。[18]
關於Java API
的小常識:以javax
開頭的包就會知道他之前曾經是擴展。API
是程序員的得力幫手,好工具,因此要善於查詢API
並熟練的掌握,會讓你編碼更從容,優雅。你們能夠上java.sun.com
的網址裏面去在線查找API
,也能夠下載離線到本地。[19]
使用import
會把程序變大嗎?編譯過程會把包或類包進去嗎?答案:import
與C
的include
並不相同。運用import
只是幫你省下每一個類前面的包名稱而已。程序不會由於用了import
而變大或變慢。[20]
爲什麼我沒必要import
進String
類或System
類?答案:要記得java.lang
是個預先被引用的包。由於java.lang
是個常常會用到的基礎包,因此你能夠沒必要制定名稱。java.lang.String
與java.lang.System
是獨一無二的class
,Java
會知道要去哪裏找。[21]
繼承父類,並覆蓋(Override
)方法後,可讓子類更好的擴展從父類繼承下來的功能,如:public void roam(){super .roam();//your code}
,注意super
的做用,它可讓你在父類的方法上,加上額外的行爲,這是很是重要的一種寫法!必定要學會使用。[22]
繼承的意義:避免了重複的程序代碼,定義出共同的協議。是多態的一種手法,如:Animal myDog = new Dog();
方法的參數跟返回結果均可以使用這種多態的手法,能夠大大的提升你的方法的擴展性。[23]
覆蓋的原則:參數必需要同樣,且返回類型必需要兼容,不能下降方法的存取權限。[24]
還有一種方法叫重載(overload
),重載的規則:返回類型能夠不一樣,不能只改變返回類型,能夠更改存取權限。注:重載跟多態毫無關係,重載的使用情景在本類中,重寫的使用情景在繼承的時候體現。[25]
接口是一種100%
純抽象的類,它是多態
和java
的重點。[26]
抽象類的聲明方法:在類的聲明前面加上抽象類關鍵詞abstract
就好,如:abstract class Animal{public void roam()};
你們想想爲何要設計出抽象類,緣由就在於:像Animal
這樣的對象太抽象,不該該被實例化出來,編譯器不會讓你初始化出現類,若是你要想使用它,那就繼承它吧?。[27]
抽象的類表明此類必需要extend
過,抽象的方法表明此方法必定要被覆蓋過。若是你聲明出一個抽象的方法,就必須將類也標記爲抽象的。你不能在非抽象類中擁有抽象方法。注:子類也能夠不用實現抽象方法,?,只要你把子類也聲明爲抽象類,讓後讓你子類去繼承你,讓它去實現這個抽象方法,這個機制叫抽象機制,將實現的負擔轉給下層。這個手法很重要。[28]
就算你不知道,但實際上全部的類都是從對象給繼承出來的,沒有直接繼承過其餘類的類會是隱含的繼承對象。[29]
使用Object
類型的多態引用是會付出代價的,由於Object
實在是辨識度過低,不少時候都要必須強制轉換類型才能用,很不方便。並且最重要的一點就是:就算你知道對象有這個功能,編譯器仍是會把它看成通常的Object
來看待。編譯器只管引用的類型,而不是對象的類型。注:(很差懂?哈哈,如:Object o = al.get(index);o.bark();
//這個o
實際上是一個Dog
類型的對象,有bark()
的方法,可是由於是編譯器只知道他如今是Object
類型,這個類型是沒有該方法的,因此編譯器不會經過編譯,懂了吧?)。[30]
當你在不知道是否是能夠把Object o
對象轉化成Dog
類型,怎麼辦?簡單:if(o instanceof Dog){Dog d = (Dog) o;}
。[31]
Java
爲何不支持多重繼承,由於會致使「致命方塊」
,什麼是「致命方塊」
,舉個例子:當你繼承兩個父類的時候,恰巧兩個父類有同樣方法,可是裏面的實現卻不同,你說作兒子的怎麼知道我會繼承那個方法,?,這就是問題,編譯器也不知道,因此這就是不支持多重繼承的緣由。[32]
接口能夠用來解決多重繼承的問題,卻又不會產生致命方塊這種問題,由於它根本就沒有實現,因此木有關係。android
聽說每一個人在必定時間內接受的信息量都是有限的,由於信息量有點大,畢竟七百頁的好書,因此我準備寫續集啦,但願你們帶着思考的心態去理解閱讀,我相信,對你們絕對有好處的。續集將陸陸續續的推出,敬請期待。?程序員