教她寫代碼的那些日子 8 類和對象

你是否也有那麼一段往事,一直塵封在心底,偶爾會因爲一首歌或者一句電影臺詞,讓那封印有所鬆動,一些影像慢慢浮現在腦海。你或許會覺得遺憾,會懊惱,會責問自己爲什麼不堅定一點,爲什麼不勇敢一點。人生大抵如此,失去了才明白,擁有的纔是最珍貴的,故而才常聽一句話:活在當下,珍惜眼前。

當趙雷的那首《成都》響起的時候,她臉上的笑容突然變得有些僵硬,我想這就是那首揭開她心底封印的歌吧。

”有些事過去了,就讓它隨風而去吧。“我不知道該如何安慰,這是我此刻唯一能想到的一句安慰人的話,所以我痛恨着我的直男癌。

“你知道我爲什麼要學寫程序嗎?”她突然問我。

“爲了有一技傍身。”我記得她這樣說過。

“這是一方面吧,更主要的是整天沉浸在理性的思維裏,就不會去傷春悲秋,老是傷春悲秋不好。”

“哦?”我沒想到學寫程序盡然有如此功效,她的思想真是特別。

“你還真是個特別的人,全世界這樣想的,估計也只有你一個人吧。”

“那倒未必只我一人。”她悠悠地說。

我正不知怎樣接話,又聽她說:“好了,不說這些了,今天我們學什麼?”

她突然地轉移話題,着實讓我吃了一驚,不過,那些不開心的事,不去聊它也好。

既然這樣,我也就順勢轉到今天要學的內容上來:“今天我們開始真正的java學習。”

“真正?”她有些驚奇,“之前學的不是java?”

“那倒也不是,只是之前學的是怎麼寫程序,從今天開始,我們要學習怎麼寫java程序。”

“有什麼不一樣嗎?”

“當然不一樣,首先我們要明白一個概念,那就是面向對象,Java是面向對象的編程語言。”

“還是不懂。”她搖了搖頭,顯然我又是說了一句廢話。

“面向對象是更高級的一種編程思想,相比較以前的面向過程的編程思想,它更接近現實世界。”

我想在她看來,我依然在喋喋不休地講着廢話,因爲她的眼神依然是迷惑的。

“這麼說吧,面向對象是站在上帝的視角來看待世間萬物,而面向過程還是站在凡人的視角看事物。”我努力解釋着什麼是面向對象的編程思想,因爲這很重要,這是學習Java的基礎。

“所以Java是更高級的編程語言,就是因爲它是上帝視角看待事物的?”她終於有所領悟。

“是的。”我肯定了她的想法,但我知道她還是沒有明白什麼是面向對象,於是我接着說:“你回想一下,你前面寫程序是一個怎樣的過程。”

“怎樣的過程?”她撓撓頭,回憶着學習編程以來,寫過的程序,以及寫程序的過程,“就是先想想怎麼寫,然後就按照一定思路去寫就是了。另外,爲了代碼整潔一點,會把某些代碼封裝到一個方法中。”

“沒錯,這就是面向過程的編程思想,這時你一直在想的是要實現某個功能,程序的流程應該是怎麼樣的。”

“是呀,寫程序不就是這樣嗎?”

“所以你需要忘記,忘記之前的一切,才能接收新的更好的事物。”

顯然我這句話有些一語雙關的意思,但她似乎沒有聽出來。

“我發現你也挺囉嗦的,你還是快講什麼是面向對象吧。”

“好吧。”我只好接着面向過程與面向對象的差別繼續說,“之所以面向對象更高級,就在於,遇到問題,你不應該去想怎麼設計程序的流程,而是應該去想怎樣去創造一個人或者一個事物,讓它去解決問題,這就是面向對象的上帝視角。”

“還是有點抽象啊,能否再具體?”

“這麼說吧,面向對象是接近於現實世界的,你想想現實世界是怎麼樣的。”

說到這裏,我停下來,看向她,讓她去想一下現實世界的模樣。

“是怎樣的?”她居然想都不想,直接問我。

我有些驚愕,隨即想到,她或許以爲我只是自問自答,而她只是需要配合一下我而已,於是我接着說道:“你看,現實世界是不是由各種事物構成的,比如地球、各種植物、各種動物以及人類等等,這些事物各自按照自己的規律進行生長和運動就構成整個世界。”

聽到我的描述,她想了想說:“確實是這樣。”

“面向對象的編程思想也是這樣的,所以在java中所有一切都是由一個個個體構成,這裏的個體就是對象。”

她沒說話,一雙美目看向我,示意我繼續,但我卻向她提出一個問題:“如果你是上帝,你要怎麼去創建這個世界呢?”

“我不知道。”她很乾脆地回答。

“這麼說吧,假如你是女媧,你要造人,你會怎麼做?”

“不知道。”她依然簡單直接地回答。

“好吧,那你是不是得先想想人應該是什麼樣的?”

“嗯,不用想啊,人就是那樣啊,一個頭,兩隻手,兩條腿。”

“你這不就是在想了人是什麼樣的嗎?”

“是嗎?”她有些疑惑。

“好吧,那我們就按你的設想來造人。”我忽略掉她的疑惑,繼續說:“首先我們就要對人進行一個歸類定義,然後再按照這個定義進行個體地創建。這就是面向對象編程的做事流程,要創建對象,就得先有對象的歸類定義,這個歸類定義就是類。”

“還是來看例子吧。”我沒等她說出怎麼寫代碼的問題前就拿過她的筆記本電腦開始敲代碼。

第一個例子:

編譯運行:

“看到沒,我們要創建人這個對象,首先我們先定義了人這個類。定義一個類是用關鍵字class來標示的,在class後面的大括號裏面的內容就是對一個類的定義。”

“嗯,瞭解了。”她看着代碼點了點頭說。

“定義一個類有3個部分可選,它們分別是:表示事物特徵的屬性,也叫成員變量;表示事物行爲的成員方法;以及用來設置事物初始樣子的構造方法。”說到這裏我問她,“在我寫的這個人類的定義中,哪些是屬性,哪些是成員方法,哪些是構造方法?”

“這個很簡單啊,你寫了註釋的嘛。”她一邊看着代碼一邊說:“2到7行是屬性,9到16行是構造方法,18到21行是成員方法。”

“完全正確。”我說,其實想來也是,這麼簡單的問題,而且我還寫了註釋,她要分辨不出來的話,那纔是奇怪呢。

“看來你是懂了,那麼你來寫一個呢。”看她躍躍欲試的樣子,我接着說。

“我也正有此想法,可是寫什麼呢?”她苦惱起寫什麼來。

“那你就創造幾個女人吧。”我說,我也沒想到什麼作爲例子的事物,想法還是停留在女媧造人上面。

“女人和人有什麼不同嗎?你都寫了,讓我照抄一個?”她顯然沒找到人和女人的不同。

“女人有一個很重要的屬性就是顏值啊。”我提醒她。

“好像是哦。”她笑了,“那就看我的。”

說完,她拿過電腦開始寫起代碼來。

她寫的代碼:

編譯運行:

“怎麼樣?”她開心地說。

“不錯是不錯,不過有點自戀啊,哈哈!”我笑了,因爲我注意到那個叫小花的女人的顏值,她設置的是100分,小花是她的名字。

“難道我不美嗎?”她眨巴着眼睛,盡力擺出嫵媚的姿勢,看着我說。

“美美。”我連聲稱讚,雖然故意做出敷衍的神情,但真心是覺得她很美的。

“哼。”她哼了一下,恢復了正常的坐姿,然後又說,“有一個問題,構造方法中這些this是幹嘛的?”

“this用來指代當前對象。”我隨口回答着。

“不懂。”她說,然後做出一副洗耳恭聽的神態。

我沒想到這對於java程序員來說幾乎是常識的知識點,她卻說不懂,但隨即我又想到她並不是java程序員,她只是一個開始學習Java的小白,不懂是正常的,懂纔有些不正常,於是我耐心給她講:“this就是代表了你基於這個類創建的對象。因爲類的對象,要在用new關鍵字創建後才存在,所以在類裏面就用this來指代將來會被創造出來的對象。對了,你應該知道了,創建一個對象是用new這個關鍵字吧?”

“嗯,已猜到是這樣。”她面無表情地說,我知道她在思考‘this’的問題。

“這麼說吧,在創建對象的時候,其實是先創建了一個各屬性的值都默認的對象,然後再調用構造方法,在構造方法中我們做了一件事,就是將參數的值賦值給對象對應的屬性,你知道的等號就是賦值。”

“這樣的話,我似乎懂了,其實這裏可以這樣寫。”她說着,改了改代碼。

她改過的代碼:

編譯運行:

“可以將對象屬性的賦值寫在創建對象之後,用點號來表示對象和屬性的從屬關係。而構造方法裏面的賦值其實和寫在創建對象之後屬性賦值是一樣的,只是在類裏面不可能知道以後創建的對象的名字,所以就用this來代替。”程序正常運行後,她說出了她的理解,末了她還帶了一句:“我說得對不對?”

“說得對極了。”我說,“還有一點,this是可以省略的,你知道嗎?”

“哦,知道了。”

“那你知道,爲啥之前我們寫在構造方法裏面的賦值語句中的this沒有省略嗎?”

“哈哈,想考我嗎?這個還不明顯,是因爲我們定義的參數的名稱和屬性的名稱一樣了,如果不寫this的話,就成參數自己賦值給自己了。”

“好吧,看來我小看你了。”

“變量的作用域和方法的參數我可是認真學了的,構造方法也是方法嘛,道理應該是一樣的。”她得意地說。

“你厲害。”我盡無話可說了,只能說出這樣一句讚賞的話來。

不過她卻忽視掉了我對她的讚賞,自顧自地得意了一會兒,然後說:“類和對象就講完了?應該不會就這麼點內容吧?”

“當然不會只有這麼點內容,這只是一個入門,你現在算是入門了。”

“哦,才入門啊?那你快講吧,乘我現在正求知若渴。”她顯然有些失望,不過很快又表現出強烈的求知慾望來。

“先問你一個問題,人和女人是什麼關係?”我決定還是從一個問題開始。

“女人是人的一種啊,還有一種是男人嘛。”

“對,它們是從屬關係。在java中,這種關係我們叫繼承關係,也就是說女人是繼承於人的,人叫女人的父類,女人叫人的子類,當然還有男人也是人的子類。”

“嗯,讓我想一下。”她說完,陷入了一陣思考,而我也很知趣地沒有去打擾她。

“那這樣的話,有很多例子。比如,動物就是人的父類,人是動物的子類。”她突然擡起頭來說道。

“對對,你說得很對。”

“哈哈。”她有些得意自己的聰明,沒等我說什麼,她又提出了她的疑問,“不過這和寫程序有什麼關係呢?”

“有關係的,這樣的繼承關係我們是可以用程序表達出來的,我還是寫個例子,你看了就明白了。”

我寫的例子:

編譯運行:

“你看,其實很簡單,用extends這個關鍵字來標識繼承關係就好了。”我一邊說着,一邊給她看。

“哦,我記住了。”她說,“繼承後,子類就擁有了父類的屬性了,是不是?”

“一般情況下,是這樣的。”她的觀察能力果然沒讓我失望,我故意沒說,她也看出來了,這裏男人和女人這兩個子類繼承了人這個父類,所以這兩個子類裏面就有了name這個屬性,也正是這樣,在子類中就可以直接使用這個屬性。

“哈哈,這樣好,這樣就不用重複寫那麼多代碼了,這個繼承很好。”她感嘆着繼承的好用,接着又提出對我說的一般情況的疑問,“一般情況能把父類的屬性繼承過來直接使用,那什麼情況下不能呢?”

“這個就要說到java的訪問控制權限了。”我說,“還記得在學方法時提到的public、protected、private這幾個訪問控制修飾符嗎?”

“記得,不過不是很明白。”

“嗯,這樣吧,我們先來看一個表格吧。”說着我在網上找到一個表格給她看。

網上找的表格:

看了這個表格,她擡起頭來,茫然地看向我。

“好吧,先不管這個表格,我們先來說說包吧。”在她發問之前,我已明白她所茫然的是什麼,“你有沒有發現,我剛剛寫的代碼裏面,定義的人這個類是用的Person,而不是之前的Human?”

“是呀,爲什麼?”

“因爲之前的類已經用過了,也因爲這兩個類都在同一個包裏面(都是默認包,即無名包),所以就衝突了,如果再以Human定義一個類的話,計算機就不知道你用的是哪個定義了,所以有了包這個概念後,就可以在不同包下面定義相同名字的類了。就像你在同一個文件夾下面不能放名字相同的文件,在不同文件夾下面就能有相同文件名的文件一樣。而事實上類文件存放的文件夾也是和包名是一致的。當然,包和文件夾一樣,可以對類進行歸類,相關的類,一般是放在一個包下面。有了包以後,類就有了一個全名:包名.類名。比如系統包java.util下面的類Scanner的全名就是java.util.Scanner。”

我一口氣說了一大段理論,從她的眼神中我看出來,她還有些似懂非懂,於是我決定寫幾個例子,這樣她就能明白了。

“我寫幾個例子,你就明白了。”我說着,開始在電腦上敲起代碼來。

代碼文件目錄結構:

代碼:

com/luoye/Human.java:

com/luoye/Man.java:

com/luoye/Woman.java:

com/luoye/HumanWorld.java:

com/xh/Man.java:

com/xh/Woman.java:

com/xh/HumanWorld.java:

編譯運行:

錯誤示例的編譯:

“呀,報錯了。”

“是呀,你知道錯哪裏了嗎?”

“讓我看看。”她說着,認真看着代碼。

過了一會兒,她問我:“那個super是幹什麼的?”

我驚奇於她思維的跳躍,但也喜歡她這樣不懂就問的性格,於是我說:“那個指代父類對象,和this有些相似。”

“哦。”她說。

我沒能從這個字聽出來她是懂了還是沒懂,但這個問題似乎意會比言傳更有用一點,所以我不再苦思怎麼給她解釋了,我相信她最終是能明白的。

“找到程序報錯的問題了嗎?”我決定回到程序的報錯上面來。

“嗯,它不是報錯說,Human的屬性不是公共的嗎,那改成公共的應該就可以了。”

“那麼改一下看看呢。”

她改過的Human:

編譯運行:

“果然是這樣。”程序運行後,她有些小興奮地說。

“那麼,通過這些例子,是不是瞬間就明白我剛剛說的那一大段了?”我問她,我相信通過這幾個例子,她能明白。

“嗯,大概明白了吧。”她想了想說。

“包的聲明語句只能寫在類文件的開頭,而且在一個類文件中只能有一個包聲明語句,也只能有一個訪問控制權限是public的類。在使用不是本包定義的類時,需要用關鍵字import將類引入進來,可以引入一個類,也可以用*表示引入那個包下面所有的類。當然,如果出現名字衝突,我們也可以用類的全名來避免。”我怕她看不出這幾個隱藏的知識點,特意強調道。

“知道了。”

“好了,明白了包的概念,那這個訪問控制權限的表應該也看得懂了吧。”我翻出剛纔百度出來的表,說道。

“嗯,也差不多看得懂了。”

“哈哈,聰明。”

“你就別誇我了,我現在腦袋都快爆炸了,一下子接收這麼多知識,我要好好消化一下才行,今天就講到這吧。”

“遵命,我...”我本想說我的女王大人,但突然覺得這幾個字從我嘴裏說出來顯得有些輕佻了,故而將後面幾個字生生地嚥了回去。

然而,她似乎根本沒在意我說什麼,自顧自地思考和寫代碼去了。

 

 

ps:

這一節的幾個關鍵點:面向對象、類、對象、繼承、包、訪問控制權限

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章