張 峰,趙衛(wèi)東,鄭永果,仇麗青
(山東科技大學 計算機科學與工程學院,山東 青島 266590)
Java具有跨平臺、安全性高、健壯性等特點[1],已經(jīng)在企業(yè)級應用、桌面應用、移動應用等多個領(lǐng)域得到廣泛應用,成為當今軟件開發(fā)領(lǐng)域最流行的編程語言之一。JavaSE是整個Java技術(shù)體系的基礎(chǔ),而Java作為一種面向?qū)ο蟮木幊陶Z言,接口又是JavaSE中面向?qū)ο缶幊讨械闹攸c[2]。理解接口的含義,熟練使用接口編程,對于學生后續(xù)學習面向?qū)ο蟮姆治?、設(shè)計及開發(fā)至關(guān)重要。
在JavaSE面向?qū)ο蟛糠值慕虒W中,一般在類、對象、繼承等基本概念之后講授接口。由于接口的定義和使用與類、抽象類類似,在教學中發(fā)現(xiàn),學生往往在編程過程中不能靈活使用接口,在做具有較強應用性質(zhì)的編程題目時,更習慣使用類或者抽象類,這說明,初學Java的大部分學生還沒有真正理解接口的含義和編程方法。
為解決接口教學中存在的問題,文獻[2]站在軟件工程的立場,結(jié)合面向?qū)ο蟮脑O(shè)計原則和設(shè)計模式的部分內(nèi)容,對教學內(nèi)容進行了拓展。筆者曾借鑒文獻[2]的方法組織教學內(nèi)容,但在實際教學中同樣遇到一些問題:①由于JavaSE課程內(nèi)容面向初學者,學生對面向?qū)ο蟮睦斫膺€不夠深入,而面向?qū)ο蟮脑O(shè)計原則和設(shè)計模式等內(nèi)容對面向?qū)ο蟮囊蟾?。對于大多?shù)JavaSE初學者來說,此時引入面向?qū)ο蟮脑O(shè)計原則及設(shè)計模式的內(nèi)容并不一定適合于大多數(shù)學生;②從課時安排來看,接口部分通常限制到2~3個學時,而引入面向?qū)ο蟮脑O(shè)計原則、設(shè)計模式等內(nèi)容會延長授課學時;③教學中采用的實例相對抽象,不是生活或工程應用中的典型實例,在調(diào)動學生的學習興趣和積極性方面還存在不足;④沒有采用當前流行的MOOC、翻轉(zhuǎn)課堂等教學技術(shù)與方法[3],教學過程中與學生的互動不足,學生的學習積極性和學習效果還需進一步提高。
整個教學過程通常用2個學時,教學步驟、內(nèi)容以及采用的教學方法如圖1所示。
接口教學中,首先要讓學生理解Java接口的含義,重點理解“接口即規(guī)范”。首先介紹“寬定義”和“窄定義”的接口,讓學生知道之前學過的諸如C、C++里面提到的函數(shù)、方法是“寬定義”的接口,即通常所說的“API”中的“I”所表示的Interface。然后講解Java接口是Java語言提供的一種“窄定義”的接口,是Java中定義的一種特殊類型,表示的是一種規(guī)范。
圖1 接口教學內(nèi)容與方法
為了讓學生理解“接口即規(guī)范”,在文獻[4]的PCI接口實例的基礎(chǔ)上,通過學生生活中更加熟悉的USB接口來講解,主要內(nèi)容包括:①USB是一種規(guī)范和標準,主板廠商為了支持USB設(shè)備,需要提供符合USB標準的插口;USB設(shè)備生產(chǎn)廠商(如U盤制造商),為了能夠用于主板的USB插口,必須按照USB規(guī)范來生成產(chǎn)品;②介紹主板與USB設(shè)備之間基于USB規(guī)范的耦合,引出組件之間基于規(guī)范耦合的知識點,為后面介紹基于接口的編程做好鋪墊。
在教學方法方面,我們通過一個MOOC短視頻提前發(fā)布給學生,學生課下自學,作為上課時翻轉(zhuǎn)課堂的基礎(chǔ)。
我們首先講解接口的定義、類實現(xiàn)接口等基礎(chǔ)知識。為了便于學生理解,從“能力”的角度講解類對接口的實現(xiàn):一個類實現(xiàn)了一個接口,則需要實現(xiàn)該接口中定義的所有方法,也就說明該類滿足了所實現(xiàn)的接口要求的“能力”。這種“能力”是通過實現(xiàn)接口中的方法來體現(xiàn)的。在此基礎(chǔ)上,介紹Java中不支持多繼承、類可以實現(xiàn)多個接口、接口與抽象類的比較等其他知識點。
從教學過程來看,接口部分的基礎(chǔ)知識并不難,關(guān)鍵是讓學生真正理解接口的作用。為此,后續(xù)教學內(nèi)容的重點是通過實例來講解接口的應用,這些實例應該是學生熟悉或者工程實踐中常用的,才能加深學生的理解。為此,我們在教學中用Java代碼模擬2.1中USB接口的實例,讓學生加深對“接口即規(guī)范”“面向接口編程”的理解。圖2給出了實例Java代碼對應的UML類圖,以及兩個設(shè)計存在問題的UML類圖。
首先,通過代碼模擬相關(guān)的接口和類,如圖2(a)所示。具體講解的內(nèi)容包括:接口USB定義了USB規(guī)范,該規(guī)范定義了方法start和stop;提供USB接口的設(shè)備,包括無線網(wǎng)卡類WirelessNetCard和U盤類FlashDisk,都實現(xiàn)了USB接口,它們的對象都具備USB接口規(guī)范所規(guī)定的“能力”,即都具有start和stop方法。
其次,講解面向接口的編程,包括主板類MainBoard的成員slot,表示該主板所支持的插槽,其類型USB指明了該插槽所支持的規(guī)范。也就是說,MainBoard類提供的插槽slot支持USB設(shè)備。MainBoard類提供了setUSB方法,可以傳入任何支持USB的設(shè)備對象,即可以傳入任何實現(xiàn)了USB接口的類的對象。例如,可以傳入無線網(wǎng)卡類WirelessNetCard對象或U盤類FlashDisk對象。通過圖2(a)的例子,可以形象地說明面向接口編程的優(yōu)點: MainBoard類的成員slot是USB類型的,從而通過slot可以引用任何實現(xiàn)了USB接口的類的對象。從現(xiàn)實來說,可以理解為主板提供了一個支持USB規(guī)范的插槽,任何符合USB規(guī)范的設(shè)備都可以插在該主板的插槽上。在該實例中,類MainBoard與USB接口之間存在依賴關(guān)系,但MainBoard只依賴于USB接口,而不依賴于任何具體類,從而實現(xiàn)了松耦合。
圖2 USB實例的類圖
最后,介紹設(shè)計存在問題的情況,給出圖2中(b)和(c)兩個反例。在圖2(b)中,MainBoard類依賴于WirelessNetCard類,導致該主板類MainBoard提供的插槽只能接入無線網(wǎng)卡設(shè)備;同理,圖2(c)中的MainBoard類依賴于FlashDisk類,導致該主板類MainBoard提供的插槽只能接入U盤。在圖2(b)(c)中,兩個MainBoard依賴于具體實現(xiàn)類,導致了它們與具體類之間的緊耦合。通過將圖2中(a)與(b)(c)兩個反例進行對比,讓學生理解面向接口編程的優(yōu)點,也加深對接口的理解。
在本部分內(nèi)容的教學方法方面,基礎(chǔ)知識部分內(nèi)容相對簡單,通過MOOC視頻讓學生課下自學,同時留下思考題,讓學生看完視頻后,自己思考USB實例該如何設(shè)計。上課時讓學生講解自己的設(shè)計,一起討論,最后由老師點評設(shè)計的優(yōu)劣。從實際的教學來看,部分學生的設(shè)計結(jié)果中出現(xiàn)了圖2中(b)(c)兩種設(shè)計方式。
2.2中模擬USB實例的Java代碼沒有實際的運行效果。為了進一步加深學生對接口功能的理解,我們通過一個實際開發(fā)中的常用功能來進一步講解。該實例使用了JDK集合框架中Arrays類的靜態(tài)方法sort。具體的教學過程和教學方法如下。
第一,通過使用Arrays.sort(Object[]a)方法對String數(shù)組排序的一段代碼,演示該方法的排序功能,并通過API文檔的查看,說明該方法可以實現(xiàn)任意類型對象數(shù)組的排序。然后,采用啟發(fā)式教學方法,引導學生思考一個問題:如何實現(xiàn)sort(Object[]a)的功能?進一步引導學生思考:如果要實現(xiàn)該方法,是否需要知道什么前提?在教學過程中,學生一般會考慮到需要知道這些待排序?qū)ο蟮呐判蛞罁?jù)。進一步講解,方法形參是Object[],可以對任何對象數(shù)組排序,因此,要求這些待排序?qū)ο竽軌蜻M行比較,即滿足“可比較”這一規(guī)范,從而引出需要待排序?qū)ο笏鶎兕悓崿F(xiàn)一個描述“可比較”這一規(guī)范的接口,最終給出需要實現(xiàn)的Comparable接口。在此基礎(chǔ)上,查看Comparable接口的API文檔、String類的implements Comparable聲明,以及String類對Comparable接口中的compareTo方法的實現(xiàn)。
第二,引導學生思考Arrays.sort(Object[]a)實現(xiàn)排序的方法。講解內(nèi)容包括:排序中的兩個基本操作是比較和交換, sort方法實現(xiàn)的關(guān)鍵是如何比較兩個對象。即如何比較a[i]和a[i+1]?教學中讓學生先思考,然后找學生到教師機上編寫代碼,共同討論,教師點評給出正確答案;最后,通過查看sort方法的源碼來驗證。該教學過程進一步加深了學生對接口功能的理解,同時也加深了對Java中多態(tài)的理解。
第三,針對前面課程中的Java類實例,如描述學生的Student類,讓學生自己完善Student編碼,使得Student數(shù)組可以使用Arrays.sort(Object[]a)排序。同時,要求提供多種排序方法,如根據(jù)學號、成績、姓名進行排序,還可以升序、降序排列。通過練習,讓學生熟悉使用Arrays.sort方法排序這一實用功能,加深對接口的理解。
最后,留給學生幾個稍有深度的問題課下思考,再次上課時通過討論、提問的方式講解。相關(guān)問題包括:①Arrays.sort(Object[]a)方法需要排序的類實現(xiàn)Comparable接口,但通過實現(xiàn)該接口中的compareTo方法只能實現(xiàn)一種排序方式。如果排序需求發(fā)生了改變,或者不同情況下需要不同的排序功能,該如何實現(xiàn)?通過該問題的思考,學生能發(fā)現(xiàn)僅僅使用Comparable接口所存在的問題,從而引出讓學生自學的Comparator接口,進一步加深對接口的理解和熟練程度。②Arrays.sort(Object[]a)方法為何要求排序的對象所屬類實現(xiàn)Comparable接口,而不是繼承一個抽象類或一個普通類?通過該問題的思考,學生會加深Java中不支持多繼承以及一個類可以實現(xiàn)多個接口的理解。③Arrays.sort(Object[]a)方法內(nèi)部使用待排序?qū)ο蟮腸ompareTo方法實現(xiàn)對象之間的比較,那么,待排序?qū)ο笏鶎兕愂欠窨梢詢H添加compareTo方法而不聲明實現(xiàn)Comparable接口?通過該問題的思考,結(jié)合sort方法的源碼,學生可以加深對接口以及多態(tài)的理解。
在教學方法方面,我們關(guān)于本小節(jié)的全部授課內(nèi)容通過4個MOOC視頻提供:①Arrays.sort方法基本功能介紹;②Comparable接口簡介;③sort方法實現(xiàn)原理與源碼分析;④Student排序?qū)崿F(xiàn)。第一個視頻在課前發(fā)布給學生,作為基礎(chǔ)知識讓學生學習,而后3個視頻則在翻轉(zhuǎn)課堂后提供給學生復習。這樣做是為了讓學生在課堂上積極思考,通過啟發(fā)式教學,讓學生思考、討論sort方法能夠排序的前提、sort方法的源碼實現(xiàn)、Student排序這3個關(guān)鍵問題,提高他們的聽課效率,而課后通過MOOC視頻的觀看加以鞏固。最后,學生可以課下自學Comparator接口,并思考上述幾個有一定深度的問題。
完成上述3小節(jié)的內(nèi)容后,JavaSE面向?qū)ο蠡A(chǔ)部分的接口教學就完成了。后續(xù)授課內(nèi)容中很多章節(jié)會用到接口,通過繼續(xù)強化接口的應用,進一步鞏固接口部分的基礎(chǔ)知識。例如,JDK集合部分提供了List、Set、Map、Iterator等接口,該部分在編碼時經(jīng)常用到面向接口的編程;JDBC中提供了一組接口,而相應數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫驅(qū)動中包含了這些接口的實現(xiàn)類。同樣,Servlet中提供了若干接口,這些接口的實現(xiàn)類則由各種Java Web應用服務(wù)器來提供。學生通過在這些后續(xù)內(nèi)容中回顧涉及的接口的基礎(chǔ)知識,更進一步加深對接口、接口即規(guī)范的理解,從而熟練使用接口進行開發(fā)。
上述教學過程和教學方法結(jié)合MOOC視頻和翻轉(zhuǎn)課堂,明顯改善了接口部分的教學效果。一方面,從學生學習過程的表現(xiàn)來看,學生在課下學習視頻后,翻轉(zhuǎn)課堂時學生已基本掌握了接口的主要知識點。在翻轉(zhuǎn)課堂上,通過啟發(fā)式教學方法的運用,討論、點評USB和Arrays.sort兩個典型實例,學生在課堂上參與討論和點評的積極性有了很大提高。另一方面,從學生的作業(yè)、實驗和考試情況來看,絕大多數(shù)學生理解了接口的含義,設(shè)計和編碼中能夠熟練使用接口,后續(xù)課程在講解集合類、JDBC、Servlet等章節(jié)時,大多數(shù)學生能夠理解其中涉及的接口方面的知識。
總體來看,上述JavaSE接口教學的授課內(nèi)容涵蓋了主要知識點,未涉及較有深度的其他課程內(nèi)容。結(jié)合MOOC視頻、課上翻轉(zhuǎn)加講授,一般可以在2個學時內(nèi)完成。該教學過程已經(jīng)在實際教學中實施,較好地提高了接口部分的實際教學效果。
接口是Java面向?qū)ο蟪绦蛟O(shè)計中最基本、最重要的內(nèi)容之一,也是整個Java技術(shù)體系和后續(xù)軟件工程相關(guān)課程的基礎(chǔ)。通過引入生活中和工程實際中的典型實例,結(jié)合MOOC視頻以及翻轉(zhuǎn)課堂上的討論和點評,學生的學習積極性和學習效果有了明顯提升。當前,隨著MOOC和翻轉(zhuǎn)課堂的逐漸普及,如何更好地結(jié)合MOOC、翻轉(zhuǎn)課堂等現(xiàn)代教育理念和技術(shù),提煉更多來源于生活和工程實際應用的教學實例,推廣到程序設(shè)計和軟件工程類相關(guān)課程的教學,是需要進一步思考和探索的問題。