登陆注册
36887500000128

第128章 教学内容与课程体系改革()(69)

关键词:Java 继承 抽象类 接口 多态 匿名类

Java 是一种纯面向对象的编程语言,与另一种常用的面向对象语言C ++相比较,它具有简单、易学、与平台无关和安全性高等优点。另外,Java 还是目前使用最为广泛的网络编程语言之一。但由于它的结构体系庞大,类库较多,常使初学者望而生畏。在Java 语言的学习过程中,每个人所遇到的问题都不尽相同。本文结合自己的教学经验,对一些常见问题进行探讨,并对初学者普遍感觉较难理解的内容,如接口、多态及匿名类进行剖析,期望对Java 语言的初学者能有较大的帮助和启发。

一、初学者经常遇到的问题

(一)面向对象的程序设计(OOP)

Java 语言与面向过程编程的C 语言相比是完全不同的,从根本上说,是解决问题的思路不同。因此,不管初学者是否有C 语言的经验,这种思路的转变都需要经历很长的过程。

大部分院校对学生的教学安排是先学C ++再学Java,可是有一半的学生在学完C++语言后还没有理解面向对象的编程特点。

1.基本概念

Alan Kay 总结了面向对象语言同时也是Java 所基于的语言之一的Smalltalk 的基本特性。

(1)万物皆为对象。应到程序中,对象是一些相关的变量和方法的集合,其中变量表明对象的状态,方法表明对象所具有的行为。

(2)程序是对象的集合,对象之间通过发送消息来完成交互。想要请求一个对象完成某项功能,就必须向该对象发送一条相应的消息。

(3)每个对象都拥有其类型。每个对象都是某个类(class)的一个实例(instance)。

每个类区别于其他类的最重要特性是“可以发送什么样的消息给它”。

(4)某一个特定类型的所有对象都可以接收同样的消息。这个特性是和多态(PolymorPhism)紧密相关的。多态是OOP 中最重要的特性之一,但在实际教学实践中它是学生理解和使用的难点,本文的第二节对其进行更深入的剖析。

2.类和对象的关系

对现实生活中的对象进行抽象,只抽取与当前研究有关的本质特征,而忽略非本质特性,再将其映射为程序中的对象。具体在程序中,现实中的对象是通过一种抽象数据类型来描述的,这种抽象数据类型称为类(class)。因此,类是具有相同属性和操作的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和操作两个主要部分。在面向对象的程序设计中,类是程序的基本单元。对象是类的一个实例(instance),或者说对象是具有特殊属性和行为方式的实体。因此,类是用来定义对象的模板(temPlate)。

在Java 语言中,可以通过new 操作符调用一个类的构造方法实例化一个该类的对象。这时,内存中存放的是这个对象而不是这个类。从这个意义上理解,类是“死”的,而对象是“活”的,因为对象这个实体占有了内存空间。

(二)Java 中的变量

Java 中的变量分成员变量和局部变量两大类,而成员变量又分为实例变量和类变量两种。对于成员变量,如果声明后没有给初始值,系统会根据该变量的数据类型给其自动赋初始值,具体赋值可参见一、(六)节。而对于局部变量,在声明后必须显式赋给其初始值才能使用。

1.局部变量

在类的成员方法体内或参数列表中声明的变量称为局部变量。下述代码中m 和n 都是局部变量。初学者经常忽略的是方法参数列表中声明的变量,即m 是局部变量。

2.类变量

在类体中定义的变量称为成员变量,如上述代码中的变量i 和j。使用static 关键字修饰的成员变量称为类变量,又称静态变量,如上例中的变量i。在访问类变量时,不需要类的实例化,可以直接调用。调用时,前缀可使用类名或对象名,为增加程序的可读性,建议使用类名调用。使用一个类可以实例化的多个对象,这时所有的对象共享一个类变量,即该类变量在内存中是唯一的,与实例化对象的数量没有关系。因此,可以将网站首页用于访问计数的变量设计为类变量。初学者往往错误地认为类变量比实例变量高级,滥用类变量,容易导致不易察觉的运行时错误。

3.实例变量

没有static 关键字修饰的成员变量称为实例变量,如上例中的变量j。如果一个类有多个实例对象,那么每个对象都有自己的实例变量拷贝,它们之间相互不影响。实例变量必须在实例化对象后才可以使用。使用static 关键字修饰的成员方法称为类方法或静态方法。在静态方法中不允许使用实例变量。

(三)构造方法

构造方法是一种特殊的成员方法,它的特殊性在于:(1)构造方法的名字必须与类名一致,包括大小写;(2)构造方法只能在创建类的对象时由系统隐含调用或在某构造方法内调用另一构造方法;(3)构造方法没有返回类型。初学者容易将构造方法的返回类型说明为void,而这个编译错误很不容易查找。

1.构造方法的作用

在定义类的成员变量时,可以同时赋予初值。除此之外,对成员变量的操作只能放在方法中。

2.在继承树中构造方法的调用顺序

对于存在直接继承关系的父类和子类,如果子类中没有定义构造方法,则自动继承父类的不含参数的构造方法,并在创建一个子类的对象时自动执行。如果子类有自己的构造方法时,则创建子类的一个对象时也要先执行父类不含参数的构造方法,再执行自己的构造方法。具体来说,在实现子类的构造方法时,构造方法的调用顺序如下:

(1)先调用父类的构造方法,一直追溯到类的根源(即Object 类);

(2)如果该子类有引用类型的成员变量,则根据这些成员变量声明的顺序,调用各个成员变量的构造方法;

(3)最后才调用子类自己的构造方法。

(四)“is-a”和“has-a”

“is-a(是一种)”指继承;而“has-a(拥有)”指组合。如在上述代码中,Car 和Vehicle 是“is-a”关系,因为“小汽车是一种机动车”;而Car 和Engine 则是“has-a”关系,因为“小汽车有引擎”。由于继承在面向对象设计中的重要性,所以经常强调它的使用。于是,初学者就会有这样的观点:处处都应该使用继承。这会导致类的设计很复杂并难以被使用。实际上,在设计新类时,应首先考虑使用组合,即“has-a”关系,因为它更加简单灵活。

(五)Java中成员方法的参数传递

Java 中成员方法的参数传递究竟是“传值”还是“传地址”有很多争论,下面分基本数据类型和对象引用类型来讨论。

在Java 语言中,不同的方法中的变量各自独立使用自己的内存,不会相互影响。因此,上述代码中尽管两个变量名字都是i,但它们在内存中所占的位置不同。

(六)Java中的一些隐含规则

Java中包含一些隐含规则,不了解这些规则会使初学者感到很困惑。

首先,系统自动导入了java.lang包,相当于在程序的首行隐含加入了“imPortjava.lang.*;”语句;其次,类HelloWorld隐含继承自类Object,相当于类的声明为“classHelloWorld extends Object{?}”。因为,Java中的类是单根继承结构,除Object之外的所有类都是Object 的子类或间接子类。经常遇到的一些隐含规则如下。

(1)当类的成员变量在声明时没有赋初值,系统会自动赋给它们缺省值。如果成员变量的类型是对象引用类型,则其初值被赋为null。如果成员变量的类型是8种基本类型,即byte,short,int,long,flost,double,boolean或char。

二、Java学习中的一些难点

(一)抽象类和接口

抽象类和接口是Java语言中两个重要的对象引用类型,它们是Java语言程序设计中使用多态的基础。

1.基本概念

用关键字abstract修饰的类称为抽象类。抽象类的对象不能使用new运算符来创建,而需要产生该类的非抽象子类,由这个子类来创建对象。一个抽象类只关心它的子类是否具有某种功能,并不关心功能的具体行为,功能的具体行为由子类负责实现。用关键字abstract修饰的方法称为抽象方法。使用关键字interface声明一个接口,接口体中包括常量声明和方法声明,特别指出的是接口中的方法只有声明而没有实现。接口定义了两个对象之间进行通信的协议。使用接口的核心原因是为了实现多重继承。Java中的类是单根继承结构,不允许多重继承。为解决这个问题,引入了接口,而接口允许多重继承。初学者对接口的理解不深,事实上接口是一种特殊的类,在功能上像抽象类,为抽象方法和常量的整体声明。这一点对理解后面的接口回调过程很重要。

2.抽象类和接口的区别

虽然接口在功能上像抽象类,但它与抽象类是有区别的,主要表现在:

(1)接口中不能有非抽象的方法,但抽象类可以有;

(2)一个类能实现多个接口,但只能有一个父类;

(3)接口与类的继承无关,所以逻辑上无关的类也可以实现同一个接口;

(4)接口中不需要构造方法;

(5)接口中只能有类常量,不能有实例变量。

3.抽象类和接口的适用场合

两个毫不相关的类,如ComPuter和Door可以实现同样的功能oPen和close,因此使用接口会使程序设计更加灵活。有的初学者就提出这样的观点:接口有这么多优点,为什么不用接口代替抽象类呢?事实上它们有各自的适用场合。

(1)接口更有用一些,因为任何类都能实现(imPlements)它,即使该类已经继承了某个类。

(2)由于接口纯粹是一种API声明,使用它会使代码的设计更简洁。

(3)如果把一个接口定义为公共API的一部分,然后又要给这个接口增加一个新的方法,就会破坏实现原先接口的所有类,这时选择抽象类比较合适。

(4)如果要设计的类型要用到继承的优点时应选择将其设计为抽象类。

(5)两者可以结合起来使用。首先把设计的类型定义为接口,然后创建一个实现了该接口并且提供了可供子类使用的默认实现的抽象类。

(二)多态

面向对象编程的特点是封装、继承和多态,继承是多态的基础。很多初学者在学完一门面向对象的语言后,只记得封装和继承,而对多态缺乏感性认识,感觉它很难理解。多态是指“当某变量的实际类型和形式类型不一致时,调用此变量的方法,一定会调用到正确的版本,也就是实际类型的版本”。多态方法的版本不同的根源是方法的覆盖(override),而变量实际类型和形式类型不一致是对象的向上转型造成的。因此,首先要弄清楚方法的覆盖(override)和对象的向上转型两个概念。

1.方法的覆盖(override)

方法的覆盖是指子类中定义一个方法,该方法的名字、返回类型、参数个数和类型与从父类继承的方法完全相同。对于用子类创建的一个对象,如果该子类覆盖了父类的方法,则运行时系统调用子类覆盖的方法。

2.对象的向上转型

假设类B是类A的子类或间接子类。当创建一个子类B的对象,并把这个对象的引用放到父类A的对象中时则称对象a是子类对象b的上转型对象。对于上转型对象,要注意以下几点。

(1)上转型对象的实体是由子类负责创建的,但上转型对象会失去子类对象的一些属性和功能;具体讲,上转型对象不能操作子类新增的成员变量,也不能使用子类新增的方法。

(2)上转型对象可以操作子类继承或隐藏的成员变量,也可以使用子类继承的或覆盖的方法。

(3)当用上转型对象操作子类覆盖的方法时,就是通知其对应的子类对象去调用自己的方法,也就是子类覆盖的方法。

(4)可以将对象的上转型对象再强制转换到一个子类对象。这时,该子类对象又具备了该子类的所有属性和功能。

其中,第(3)条是理解多态的关键。

3.多态(PolymorPhism)

如果一个父类有很多子类,并且这些子类都各自覆盖了父类中的某个方法。那么当把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个上转型对象。这时,利用该上转型对象调用这个方法就可能具有多种形态,这种特性称为多态。

当增加一种继承自Instrument的新类如Stringed时,类Music中的tune方法不用做任何改动,就可以在main方法中使用语句“tune(new Stringed);”来调用类Stringed覆盖的方法Play。由于使用了多态机制,可以任意加很多这样新的类型,而不用修改tune方法。这样的程序可扩展性很好。因此,多态是一项让程序设计者“将改变的事物和未变的事物分开”的重要技术。多态机制的使用有以下限制:①多态机制只能用于对象引用类型,而不能用于基本数据类型;②多态机制只能用于成员方法,而不能用于成员变量;③多态机制只能用于实例方法,而不能用于类方法。

同类推荐
  • 受众反拨与媒介变局:党报群众工作的理论与实践

    受众反拨与媒介变局:党报群众工作的理论与实践

    本书从党报所处的发展环境入手,全面分析党报群众工作的历史经验及现实意义,探究党报群众工作的现实问题,有针对性地提出党报群众工作的改进思路。
  • 师之初

    师之初

    本书是一个乡村教师对教育,尤其是教师本身的反省与思索,内容包括:教育是一种理想、在学校不只是长身体、发现课堂教学的规律、学校教育很重要。
  • 教育新视野:中外中小学名校风采

    教育新视野:中外中小学名校风采

    虽然中国的教育经费每年都在增加,但是由于受教育的人口多,人均教育经费并不多,在长期内难以满足需求。而与此同时,社会对优质教育资源的需求却越来越迫切,最明显的表现莫过于众所皆知的“择校”现象。有关调查表明,尽管政府对义务教育阶段的择校基本持否定态度,对非义务教育阶段的择校也采取了限制人数、钱数和分数的政策,但由于没有相关具体配套的政策法规来调节、规范择校行为,择校现象自20世纪90年代初期至今越来越盛行。家长热衷于择校,而名校也乐于招收择校生,以至有的学校招收的择校生人数甚至达到学生总数的1/3以上。鉴于此,我们把中外中小学名校加以整理,以为家长和社会提供一个全面的参考。
  • 中国生存启示录

    中国生存启示录

    这是一本面对现实如何生存的启示录,一本发现人生智慧、追寻幸福生活的指南书。是中国第一部以“培育健康价值观”为专题的心灵励志书。作家、教授梁晓声把他用心灵发展出的生存智慧反哺到精神境界中,再用他从社会生活中发展出的知识浸透到心灵里去,为那些生活在社会各阶层的人们,寻找一份心灵寄托与精神生活的充实,以及能够解决一些现实问题的方法。他以平常心去思考人生和社会中的常态及潜在的问题,用从容的心态做一些新的尝试和突破,力图为大众的现实生活寻找借鉴,在现实与精神的总作用下,告诉我们他自己的生活感受,启迪人们面对各种各样的现实应该拥有怎样的生存态度。
  • 我们能做什么:胡适说中国

    我们能做什么:胡适说中国

    本书是一部可以同《旧制度与大革命》对照来读的书。这在热销的《旧制度与大革命》提出大革命并非一定发生在一个国家的贫困时期,在经济发展较好,却导致严重两极分化的时期也可能引发革命。两个时期虽然面临的问题不同,但引起的后果却可能相同。胡适的解剖刀对准的是国民党统治下的旧中国,深恶痛疾的是旧中国的种种痼疾。他主张解决中国问题的方案是建立西方式的民主制度,而历史却选择了革命。而今,在新的历史条件下,我们面临同样的风险,又听到了类似的主张。我们能做什么?胡适当年的思考也许仍然具有参考价值和借鉴意义。
热门推荐
  • 幻悠尘的时空之旅

    幻悠尘的时空之旅

    这是众神的第二部,主角悠尘是元世界三大神系中规则神系所挑选的继承者。雷区慎入,如有不测,概不负责
  • 沉沦爱

    沉沦爱

    孩提时因阴谋而聚,七年里他对她的宠溺多到无以复加,七年后他因父亲的威胁不辞而别。之后分离五年,当他们再次相聚时,他是否还爱着她,而她会再次接受沉沦他们的爱吗?一场场阴谋,一次次沉沦,虐与宠的交会,夜与昼的交缠,爱与恨的交织,他们的爱会让你也沉沦至此……
  • 轩界神

    轩界神

    人、妖、魔,气吞山河,妖言惑众,搬山倒海。各显神通,谁会是大陆之主?一个看似废柴的少年,却在自己的努力下,伴随着一个个机遇,慢慢的走到了真正的巅峰!
  • 甜心已上线,恶魔请签收

    甜心已上线,恶魔请签收

    当21世纪的宅女穿越到架空时代,当蠢萌蠢萌的小白兔变成神兽……场景一:某女:眨眼卖萌“介个,师尊,泥不素说,等我长大了让我下山去玩的咩?”某师尊:“嗯,不过你还小,山下人心险恶,本尊不放心你一人下山,本尊陪同如何?”某腹黑的师尊笑的一脸灿烂。某女:(╥╯﹏╰╥)?卒场景二:某女:瞪大水汪汪的眼睛,软糯糯地道:“师尊,能否别拎着我的尾巴?”某师尊:“不行,犯错得收惩罚!”
  • 重回明朝当海盗

    重回明朝当海盗

    大明,无汉唐之和亲,无两宋之岁币,天子守国门,君王死社稷。当为后世所敬仰。怀念热血激昂的海盗时代的朋友,本文将会带您重回明朝,招募伙伴,一起探索未知的世界。
  • 绝世孤命人

    绝世孤命人

    一个人的爱情史,一个人的友情史,精彩的故事如何展开?
  • 血火中的骨头

    血火中的骨头

    人类的折腾,惹怒了地球,于是人类悲剧了。当大灾难爆发,人类文明被摧毁后,地球上就剩下了一个高原,一块平原,嗯还有一片荒漠,面对种族延续的困难,这个奇妙的生物爆发了,不过爆发后出现的确是个大悲剧。新书奋斗在白垩纪已经开始上传,感兴趣的朋友可以去看下。
  • 神魔不死传说

    神魔不死传说

    万年弹指一挥间,游荡在天地之间的是人还是神还是魔?刑天重启,再次征战这片天地!无论你是人鬼神魔妖全部都要跪倒在战神的面前!这个世界只有一个也是唯一的真神那就是战神刑天!
  • 直播之无敌西游

    直播之无敌西游

    这是一个选择了无敌模式,拥有无敌体质,无敌商场,无敌神通逗逼主播带着一群唯恐天下不乱的直播观众,在插科打诨中玩残西游的故事。
  • 怕死

    怕死

    人的生命只有一次,有句老话叫:越老越怕死!