时间:2024-05-04
张 峰,赵卫东,郑永果,仇丽青
(山东科技大学 计算机科学与工程学院,山东 青岛 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、翻转课堂等现代教育理念和技术,提炼更多来源于生活和工程实际应用的教学实例,推广到程序设计和软件工程类相关课程的教学,是需要进一步思考和探索的问题。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!