教她寫代碼的那些日子 7 方法

這個世界技術的進步都是懶人推動的,我一直這樣認爲,故而我時常偷懶,卻也心安理得。

當我把這個觀點說給她聽的時候,她強烈地表達了不同的觀點。

“怎麼可能?”她大聲說道,“美好的世界是靠人們勤勞的雙手創造的。”

“我不否認勤勞的力量,但也不能忽略懶惰的力量。”我爭辯到。

“沒想到你是這樣的戴老師,說起瞎話來,臉都不紅一下的。”

“我沒有瞎說啊,舉個例子吧,洗衣機的發明不就是因爲懶惰嗎?”

“這麼說,好像也不是沒有道理。”她終於對自己的觀點產生了動搖。

“所以別那麼勤奮,停下來偷偷懶是很有必要的。”

“你今天怎麼神神叨叨的,有什麼話不能直接說嗎?”她似乎有些生氣,因爲她“很忙”。

“我是想說上回你寫的那個排序的代碼中,找出最小數的那段在之前就寫過,然後你在排序的代碼中又寫了一遍。”說到這我停了一下,她則翻出之前寫的代碼,然後點了點頭。

“有沒有什麼想法?”我問她。

“我寫得還可以。”她說,然後笑起來。

“你的想法很好,不過,這不是我想你有的想法。”

“虛心使人進步嘛,我明白你的良苦用心的。”

“也不是這個。”

“那是什麼?”

“難道你就不想偷偷懶嗎?前面寫過的代碼能不能有什麼好的方式直接拿過來用呢,而不是再去寫一遍。”

“額,這個,我倒沒想過。”

“所以啊,別那麼勤奮,停下來多想想是很有必要的。”

“好吧,那你說這個怎麼做呢?”她想都不想就直接問我,因爲她知道我提出這樣的問題,就是準備給她講相關的內容。

“很簡單,將具有相同功能的代碼封裝成一個方法,需要用的地方調用這個方法就可以了。”

“那麼具體表現在代碼上要怎麼寫呢?”她說着把筆記本電腦推到我面前,她倒是學會偷懶了,也不想着嘗試自己去寫了。

“也好,我先寫個例子給你看,然後再給你講是怎麼做的。”

我改過的上次排序的程序:

編譯運行:

“看到沒?找最小數的代碼寫到一個方法中了,這樣代碼看起來也整潔很多。”

“嗯,確實是這樣,那麼...”說着,她轉過頭來看向我。

我被她看得一愣,隨即明白過來,她是在等着我給她解釋怎麼寫一個方法。

“你現在知道方法就是爲了完成某一項獨立操作的若干條語句的組合。”說完我看她點了點頭,就從身邊拿來紙筆,“那麼現在我們就來看看怎麼來寫一個方法。”

說着,我在紙上寫下定義一個方法的公式來:

[修飾符] 返回值類型 方法名稱([參數表]){

方法體

[return (表達式);//返回值]

}

“其中,中括號([])代表可選內容。那你現在可以把我寫那個方法各部分套用這個公式解釋一下嗎?”

“我試試。”她說着拿過那張紙對着電腦屏幕看了看,然後就開始給我解釋起來。

“public static對應的是修飾符?”她有些不確定,見我點了點頭後,她繼續說,“int 對應的是返回值類型,getMinNumSerial對應的是方法名,float []heights,int beginSerial這兩個對應的是參數表,大括號裏面的對應的就是方法體,return n對應的就是返回值。”

“非常正確。”我對她的領悟能力之強已經不驚訝了,“不過,你一定還有很多疑問吧?”

“確實有。”

“那就說出你的疑問。”

“首先那兩個修飾符是代表什麼意思?爲什麼是可選的,在什麼情況下可以不寫,又在什麼情況下必須要寫呢?”

“public以及private和protected這幾個修飾符叫作訪問控制修飾符,用來規定類的變量和方法的訪問權限的。public表示任何地方都可以調用這個方法,private表示只能被同一個類的方法調用,protected表示的訪問權限是同一個類、同一個包以及子類。”說着我看向她,果然從她的頭頂看到了更多的問號,於是我接着說,“爲什麼是類的方法呢,是因爲java是面向對象的編程語言,所有方法都是要寫到類裏面的,不會有類外面的方法的。至於什麼是類,什麼是包,什麼是子類這些,我們後面講類的時候專門來講,現在你只要知道這些概念就是了。”

“哦,原來如此,所以所有的代碼都要寫在class XX後面的大括號裏面,我想class XX這個就是在定義一個類吧。”

“說得沒錯,你真是太聰明瞭。”

她早已習慣我這樣有些誇張和敷衍的誇獎了,所以她很心平氣和地回了一句:“那是當然。”

“那麼static這個修飾符是用來幹什麼的呢?”她接着提出她的疑問。

“這個修飾符表示這個方法是一個靜態方法,當然也可以用到類變量上,表示靜態變量。”

“這個...說了好像和沒說一樣,那麼什麼是靜態方法呢?”

我確實是說了和沒說一樣,可是要怎麼解釋呢?我有些犯難,真想說只可意會不可言傳,但我沒有說出來,而是說:“這個理解了類的一些概念就明白了,暫時你記着寫方法的時候一定要加上這個修飾符就好了。”

“好吧。”她倒也是拿得起放得下的人,不再糾結這個問題,而是換了一個問題,“返回值應該就是方法計算後得到的結果,返回值的類型和方法定義的返回值類型一定要一樣,是不是?”

“對。”

“有一個問題,按說那個程序運行的入口main也是一個方法,它的返回值類型怎麼是void,void是一個什麼類型啊,我記得沒這個類型來着。”說着她還拿出書來翻了翻,確定了確實沒有後,她接着說:“還有這個main方法爲什麼不用return返回呢?”

“嚴格來說void不是一個數據類型,它只用在方法返回值類型這裏,表示這個方法沒有返回值,既然沒有返回值,就不需要返回了。所以說方法體中的return語句是可以沒有的。”說到這裏,我突然覺得我寫在紙上的公式有些不對,return語句應該是方法體的一部分,不應該單獨寫出來。於是,我沒等她說什麼,接着解釋道:“在方法中任何地方都可以出現return這個語句,程序執行到return語句後就會退出這個方法,不管後面還有多少代碼都不會執行了。當然,return後面的返回值要根據方法定義的返回值類型來確定,如果是void的話就不需要任何返回值,否則就需要在return後面跟相應返回值類型的值,這個值可以是一個變量裏的值,也可以是一個表達式計算後得到的結果。”

“這個我明白的,就像那個getMinNumSerial方法返回的就是一個變量n裏面的值。而且這個值在方法調用後賦值給了main方法中的局部變量n。”

“對對,你說得沒錯。”我連聲說對,因爲她把我沒講明白的地方說清楚了。

“哈哈,我基本上已經搞懂這個方法了。”在聽到我說對後,她高興地笑着說。

“真的都懂了嗎?”

“真的。”

“那你給我解釋一下參數表唄。”

“這個很好理解啊。”她自信滿滿,倒是把我看成一個初學者一樣,“參數表指的是一些參數,用來在方法調用時把一些數據傳遞給方法。在main方法中調用getMinNumSerial這個方法的時候通過參數表把數組heights和變量i的值傳遞到getMinNumSerial這個方法中來,在getMinNumSerial這個方法中就可以使用了。就像你是一個買燒烤的方法一樣,我給你10塊錢,讓你去買燒烤,你拿着這10塊錢去買了燒烤,然後回來把燒烤給我,這裏10塊錢就是參數,燒烤就是返回值。”

“爲什麼要這樣麻煩呢,在getMinNumSerial方法中不能直接使用heights和i嗎?”

“當然不能,變量都有作用域的,方法中的變量就只能在定義它的方法中使用,在別的方法中是不能使用的。”

她的回答讓我很意外,我記得我沒有講過變量的作用域,然而她卻很顯然地對變量作用域這個概念很是理解。

“哈哈,不用這麼驚訝地看着我。”看到我驚訝的表情,她解釋說,“大學的時候,爲了過計算機二級,學過一點c語言,我現在發現這個和c語言差不多,通過這些天的學習,我那沉睡的c語言知識有些甦醒了。”

原來如此,難怪她會很快掌握各個知識點,原來還是有一些基礎的。

“既然這樣,那你給我講講變量的作用域,看看你的c語言知識甦醒了多少。”

“不過那是c語言,和java真的一樣嗎?”

“關於變量的作用域到目前爲止是一樣的,後面有不同的時候,我再給你講。”

“那好吧,我試試講一下。”她說着清了清嗓子,然後說:“變量的作用域是通過大括號來劃分的,在同一個大括號內的變量具有相同的作用域;在嵌套的大括號中,外層定義的變量在內層是有效的,但是在內層定義的變量在外層是無效的。還有一個例外,就是方法的參數表中變量雖然沒在大括號內,但是它們的作用域是在方法這個大括號內的。”

說完,她看向我,問:“老師,我回答得對不?”

“對,說得太對了。看來關於方法你已經沒什麼疑問了。”

“嗯,暫時沒有了。”

“那麼就上手做做練習唄。”

“好啊。”

“就把那個排序的程序裏面,交換最小數和開始找最小數的位置的數,那段代碼封裝成一個方法唄。”

“沒問題。”

她的努力成果:

程序編譯後運行沒有任何問題。

“怎麼樣?我還是很可以的。”她得意地說。

“沒錯是沒錯,不過爲什麼要把數組傳給方法又當着返回值返回呢?”

“這個還用解釋嗎?變量有作用域的啊,在exchange方法中的heights數組的作用域只在這個方法中,如果不返回的話,main方法中怎麼得到交換過的數組呢。”

“可是我覺得這裏可以不用返回值的呢,你信不信?”

“我信。”

我以爲她會說不信,然後我就可以改改程序,讓事實說服她,可她盡然說信,這讓我一時竟無言以對。

“哈哈,沒話說了吧?”她笑着說。

“你知道爲什麼了?”我以爲她已經明白了原因。

“我不知道啊,不過,我就是相信你啊。”

說實話,聽到這一句話,我突然有一種感動的小情緒了。彷彿一對患難與共的情侶,在闖蕩江湖時,女主對男主的深情告白。

正當我沉浸在想入非非的幻想時,她的聲音把我從中拉了出來:“發什麼愣呢?快給我講講啊。”

“好,我先改改程序讓你看看結果,我再講爲什麼。”

我改過的程序:

編譯運行:

“還真可以呢!”看到運行結果她驚叫道,“快講講爲什麼。”

“這個其實很簡單,在java中,除了基本數據類型是值傳遞外,其它的都是引用傳遞。”看她一臉茫然,我接着說:“值傳遞就是傳遞實實在在的值,不管是賦值還是方法中的傳參都是完全複製了一份數據給另一個變量;而引用傳遞呢,數據是一直放在一個地方,變量裏面存的只是數據在哪裏的一個信息,所以對這類變量的操作實際上一直都是操作的同一個數據。”

她依然茫然一臉,於是我想了想說:“舉個例子吧。假如你有10塊錢,你讓我幫你花掉5塊,這個時候你有兩種方案:第一種,你給我10塊錢現金,我去買個串吃了,花掉5塊錢,然後我回來給你5塊錢,這就是值傳遞;第二種,你給我一個有10塊錢的微信付款碼,我拿着這個付款碼去花掉5塊錢,我回來不用給你任何東西,你的賬戶裏就只剩5塊錢了,這就是引用傳遞。”

聽了我舉的例子,她想了想說:“你這麼一舉例我就明白了,這就是java和c的不同了吧?”

“算是一個不同吧。”我說。

“好開心,又學到一個重要的知識點。”她很開心,像一個學霸一樣,雖然我不知道她讀書的時候是不是真的學霸。

美好的時光總是溜得很快,不知不覺已經下班很久了。

“該回家了。”我說。

“呀,又這麼晚了。”她說。

於是,我們收拾了一下,肩並肩地走出公司大門,那一刻我突然有一種去牽着她的手的衝動,但我最終剋制了下來,畢竟我們只是同事關係,如果非得要把我們的關係定義得近一些的話,也不過是老師與學生的關係,我不能做一個流氓。

走到大街上,看到路邊的燒烤攤,她突然說:“想吃個串。”

“好啊,我請你。”我說。

正要走向燒烤攤,卻看到老闆推着小推車和其他小販一道一溜煙地跑了,留下一臉錯愕的我和她。

“難道你經常吃霸王餐,故而小販們看到你就跑了?”我打趣道。

“你才經常吃霸王餐呢。”她反駁道。

這時幾個穿着制服的人從眼前悠悠然地走過,我們這才恍然大悟,繼而狂笑不已。

 

 

 

 

 

 

 

 

 

 

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