張 峰,趙衛東,鄭永果,仇麗青
(山東科技大學 計算機科學與工程學院,山東 青島 266590)
Java具有跨平臺、安全性高、健壯性等特點[1],已經在企業級應用、桌面應用、移動應用等多個領域得到廣泛應用,成為當今軟件開發領域最流行的編程語言之一。JavaSE是整個Java技術體系的基礎,而Java作為一種面向對象的編程語言,接口又是JavaSE中面向對象編程中的重點[2]。理解接口的含義,熟練使用接口編程,對于學生后續學習面向對象的分析、設計及開發至關重要。
在JavaSE面向對象部分的教學中,一般在類、對象、繼承等基本概念之后講授接口。由于接口的定義和使用與類、抽象類類似,在教學中發現,學生往往在編程過程中不能靈活使用接口,在做具有較強應用性質的編程題目時,更習慣使用類或者抽象類,這說明,初學Java的大部分學生還沒有真正理解接口的含義和編程方法。
為解決接口教學中存在的問題,文獻[2]站在軟件工程的立場,結合面向對象的設計原則和設計模式的部分內容,對教學內容進行了拓展。筆者曾借鑒文獻[2]的方法組織教學內容,但在實際教學中同樣遇到一些問題:①由于JavaSE課程內容面向初學者,學生對面向對象的理解還不夠深入,而面向對象的設計原則和設計模式等內容對面向對象的要求更高。對于大多數JavaSE初學者來說,此時引入面向對象的設計原則及設計模式的內容并不一定適合于大多數學生;②從課時安排來看,接口部分通常限制到2~3個學時,而引入面向對象的設計原則、設計模式等內容會延長授課學時;③教學中采用的實例相對抽象,不是生活或工程應用中的典型實例,在調動學生的學習興趣和積極性方面還存在不足;④沒有采用當前流行的MOOC、翻轉課堂等教學技術與方法[3],教學過程中與學生的互動不足,學生的學習積極性和學習效果還需進一步提高。
整個教學過程通常用2個學時,教學步驟、內容以及采用的教學方法如圖1所示。
接口教學中,首先要讓學生理解Java接口的含義,重點理解“接口即規范”。首先介紹“寬定義”和“窄定義”的接口,讓學生知道之前學過的諸如C、C++里面提到的函數、方法是“寬定義”的接口,即通常所說的“API”中的“I”所表示的Interface。然后講解Java接口是Java語言提供的一種“窄定義”的接口,是Java中定義的一種特殊類型,表示的是一種規范。

圖1 接口教學內容與方法
為了讓學生理解“接口即規范”,在文獻[4]的PCI接口實例的基礎上,通過學生生活中更加熟悉的USB接口來講解,主要內容包括:①USB是一種規范和標準,主板廠商為了支持USB設備,需要提供符合USB標準的插口;USB設備生產廠商(如U盤制造商),為了能夠用于主板的USB插口,必須按照USB規范來生成產品;②介紹主板與USB設備之間基于USB規范的耦合,引出組件之間基于規范耦合的知識點,為后面介紹基于接口的編程做好鋪墊。
在教學方法方面,我們通過一個MOOC短視頻提前發布給學生,學生課下自學,作為上課時翻轉課堂的基礎。
我們首先講解接口的定義、類實現接口等基礎知識。為了便于學生理解,從“能力”的角度講解類對接口的實現:一個類實現了一個接口,則需要實現該接口中定義的所有方法,也就說明該類滿足了所實現的接口要求的“能力”。這種“能力”是通過實現接口中的方法來體現的。在此基礎上,介紹Java中不支持多繼承、類可以實現多個接口、接口與抽象類的比較等其他知識點。
從教學過程來看,接口部分的基礎知識并不難,關鍵是讓學生真正理解接口的作用。為此,后續教學內容的重點是通過實例來講解接口的應用,這些實例應該是學生熟悉或者工程實踐中常用的,才能加深學生的理解。為此,我們在教學中用Java代碼模擬2.1中USB接口的實例,讓學生加深對“接口即規范”“面向接口編程”的理解。圖2給出了實例Java代碼對應的UML類圖,以及兩個設計存在問題的UML類圖。
首先,通過代碼模擬相關的接口和類,如圖2(a)所示。具體講解的內容包括:接口USB定義了USB規范,該規范定義了方法start和stop;提供USB接口的設備,包括無線網卡類WirelessNetCard和U盤類FlashDisk,都實現了USB接口,它們的對象都具備USB接口規范所規定的“能力”,即都具有start和stop方法。
其次,講解面向接口的編程,包括主板類MainBoard的成員slot,表示該主板所支持的插槽,其類型USB指明了該插槽所支持的規范。也就是說,MainBoard類提供的插槽slot支持USB設備。MainBoard類提供了setUSB方法,可以傳入任何支持USB的設備對象,即可以傳入任何實現了USB接口的類的對象。例如,可以傳入無線網卡類WirelessNetCard對象或U盤類FlashDisk對象。通過圖2(a)的例子,可以形象地說明面向接口編程的優點: MainBoard類的成員slot是USB類型的,從而通過slot可以引用任何實現了USB接口的類的對象。從現實來說,可以理解為主板提供了一個支持USB規范的插槽,任何符合USB規范的設備都可以插在該主板的插槽上。在該實例中,類MainBoard與USB接口之間存在依賴關系,但MainBoard只依賴于USB接口,而不依賴于任何具體類,從而實現了松耦合。

圖2 USB實例的類圖
最后,介紹設計存在問題的情況,給出圖2中(b)和(c)兩個反例。在圖2(b)中,MainBoard類依賴于WirelessNetCard類,導致該主板類MainBoard提供的插槽只能接入無線網卡設備;同理,圖2(c)中的MainBoard類依賴于FlashDisk類,導致該主板類MainBoard提供的插槽只能接入U盤。在圖2(b)(c)中,兩個MainBoard依賴于具體實現類,導致了它們與具體類之間的緊耦合。通過將圖2中(a)與(b)(c)兩個反例進行對比,讓學生理解面向接口編程的優點,也加深對接口的理解。
在本部分內容的教學方法方面,基礎知識部分內容相對簡單,通過MOOC視頻讓學生課下自學,同時留下思考題,讓學生看完視頻后,自己思考USB實例該如何設計。上課時讓學生講解自己的設計,一起討論,最后由老師點評設計的優劣。從實際的教學來看,部分學生的設計結果中出現了圖2中(b)(c)兩種設計方式。
2.2中模擬USB實例的Java代碼沒有實際的運行效果。為了進一步加深學生對接口功能的理解,我們通過一個實際開發中的常用功能來進一步講解。該實例使用了JDK集合框架中Arrays類的靜態方法sort。具體的教學過程和教學方法如下。
第一,通過使用Arrays.sort(Object[]a)方法對String數組排序的一段代碼,演示該方法的排序功能,并通過API文檔的查看,說明該方法可以實現任意類型對象數組的排序。然后,采用啟發式教學方法,引導學生思考一個問題:如何實現sort(Object[]a)的功能?進一步引導學生思考:如果要實現該方法,是否需要知道什么前提?在教學過程中,學生一般會考慮到需要知道這些待排序對象的排序依據。進一步講解,方法形參是Object[],可以對任何對象數組排序,因此,要求這些待排序對象能夠進行比較,即滿足“可比較”這一規范,從而引出需要待排序對象所屬類實現一個描述“可比較”這一規范的接口,最終給出需要實現的Comparable接口。在此基礎上,查看Comparable接口的API文檔、String類的implements Comparable聲明,以及String類對Comparable接口中的compareTo方法的實現。
第二,引導學生思考Arrays.sort(Object[]a)實現排序的方法。講解內容包括:排序中的兩個基本操作是比較和交換, sort方法實現的關鍵是如何比較兩個對象。即如何比較a[i]和a[i+1]?教學中讓學生先思考,然后找學生到教師機上編寫代碼,共同討論,教師點評給出正確答案;最后,通過查看sort方法的源碼來驗證。該教學過程進一步加深了學生對接口功能的理解,同時也加深了對Java中多態的理解。
第三,針對前面課程中的Java類實例,如描述學生的Student類,讓學生自己完善Student編碼,使得Student數組可以使用Arrays.sort(Object[]a)排序。同時,要求提供多種排序方法,如根據學號、成績、姓名進行排序,還可以升序、降序排列。通過練習,讓學生熟悉使用Arrays.sort方法排序這一實用功能,加深對接口的理解。
最后,留給學生幾個稍有深度的問題課下思考,再次上課時通過討論、提問的方式講解。相關問題包括:①Arrays.sort(Object[]a)方法需要排序的類實現Comparable接口,但通過實現該接口中的compareTo方法只能實現一種排序方式。如果排序需求發生了改變,或者不同情況下需要不同的排序功能,該如何實現?通過該問題的思考,學生能發現僅僅使用Comparable接口所存在的問題,從而引出讓學生自學的Comparator接口,進一步加深對接口的理解和熟練程度。②Arrays.sort(Object[]a)方法為何要求排序的對象所屬類實現Comparable接口,而不是繼承一個抽象類或一個普通類?通過該問題的思考,學生會加深Java中不支持多繼承以及一個類可以實現多個接口的理解。③Arrays.sort(Object[]a)方法內部使用待排序對象的compareTo方法實現對象之間的比較,那么,待排序對象所屬類是否可以僅添加compareTo方法而不聲明實現Comparable接口?通過該問題的思考,結合sort方法的源碼,學生可以加深對接口以及多態的理解。
在教學方法方面,我們關于本小節的全部授課內容通過4個MOOC視頻提供:①Arrays.sort方法基本功能介紹;②Comparable接口簡介;③sort方法實現原理與源碼分析;④Student排序實現。第一個視頻在課前發布給學生,作為基礎知識讓學生學習,而后3個視頻則在翻轉課堂后提供給學生復習。這樣做是為了讓學生在課堂上積極思考,通過啟發式教學,讓學生思考、討論sort方法能夠排序的前提、sort方法的源碼實現、Student排序這3個關鍵問題,提高他們的聽課效率,而課后通過MOOC視頻的觀看加以鞏固。最后,學生可以課下自學Comparator接口,并思考上述幾個有一定深度的問題。
完成上述3小節的內容后,JavaSE面向對象基礎部分的接口教學就完成了。后續授課內容中很多章節會用到接口,通過繼續強化接口的應用,進一步鞏固接口部分的基礎知識。例如,JDK集合部分提供了List、Set、Map、Iterator等接口,該部分在編碼時經常用到面向接口的編程;JDBC中提供了一組接口,而相應數據庫廠商提供的數據庫驅動中包含了這些接口的實現類。同樣,Servlet中提供了若干接口,這些接口的實現類則由各種Java Web應用服務器來提供。學生通過在這些后續內容中回顧涉及的接口的基礎知識,更進一步加深對接口、接口即規范的理解,從而熟練使用接口進行開發。
上述教學過程和教學方法結合MOOC視頻和翻轉課堂,明顯改善了接口部分的教學效果。一方面,從學生學習過程的表現來看,學生在課下學習視頻后,翻轉課堂時學生已基本掌握了接口的主要知識點。在翻轉課堂上,通過啟發式教學方法的運用,討論、點評USB和Arrays.sort兩個典型實例,學生在課堂上參與討論和點評的積極性有了很大提高。另一方面,從學生的作業、實驗和考試情況來看,絕大多數學生理解了接口的含義,設計和編碼中能夠熟練使用接口,后續課程在講解集合類、JDBC、Servlet等章節時,大多數學生能夠理解其中涉及的接口方面的知識。
總體來看,上述JavaSE接口教學的授課內容涵蓋了主要知識點,未涉及較有深度的其他課程內容。結合MOOC視頻、課上翻轉加講授,一般可以在2個學時內完成。該教學過程已經在實際教學中實施,較好地提高了接口部分的實際教學效果。
接口是Java面向對象程序設計中最基本、最重要的內容之一,也是整個Java技術體系和后續軟件工程相關課程的基礎。通過引入生活中和工程實際中的典型實例,結合MOOC視頻以及翻轉課堂上的討論和點評,學生的學習積極性和學習效果有了明顯提升。當前,隨著MOOC和翻轉課堂的逐漸普及,如何更好地結合MOOC、翻轉課堂等現代教育理念和技術,提煉更多來源于生活和工程實際應用的教學實例,推廣到程序設計和軟件工程類相關課程的教學,是需要進一步思考和探索的問題。