1、类型转换
在前面的章节中,我们了解了父类和子类的关系,子类是对父类的扩展,父类是子类的抽象。也许同学们会有疑问,如果在程序中声明了一个父类变量,该父类变量能不能指向其子类对象呢?或者声明了一个子类变量,该子类变量能不能指向其父类对象呢?答案是肯定的。
例如下面的代码:
代码中Product类是父类,EBook是Product类的子类,在main方法中,声明了Product类变量,该变量指向实例化的子类对象,也就是父类变量指向其子类对象。因此,在继承关系中,子类的对象可以直接当作父类的对象使用,称为“向上转型”。
注意的是,子类对象当作父类对象使用时,不能访问其子类对象新增加的成员变量和方法。例如,在上面的例子代码中,父类变量temp指向其子类对象,因此,不能访问EBook类的formation和filesize属性。
既然父类变量可以指向子类对象。那么,父类对象也可以转换为子类对象,该转换称为“向下转型”,“向下转型”需要使用强制转换。将父类对象强制转换为子类对象时,必须确保该父类对象是子类的一个实例。
例如下面的代码:
语句“EBook ebook = (EBook) paper”在运行时,会抛出一个运行异常ClassCastException,表示类转换异常。因此,在进行父类向子类的转换时,一个好的习惯是通过instanceof运算符来判断父类变量是否是该子类的一个实例:
2、动态绑定
动态绑定是Java多态的一种表现形式,指的是代码在执行期间而不是编译时判断所引用对象的实际类型,并根据其实际的类型,调用其相应的方法。
举个例子,家用电器包含电视、电脑、冰箱等电器设备,我们可以把家用电器抽象为类(Equipment),电视(ColorTv)、电脑(Computer)、冰箱(Icebox)是作为家用电器类的子类。家用电器类提供support()方法,表示家用电器已通电,但通电后,电视、电脑、冰箱有不同的表现形式,可以用重写父类support()方法的技术来解决这个问题,这就是java 的多态和动态绑定。
类对象的动态绑定需要满足如下条件:
(1)类与类之间有继承关系;
(2)子类重写了父类的方法;
(3)要有父类变量指向子类对象;
(4)要有父类变量调用重写的方法。
例如,下面的代码首先定义了一个电器类,然后分别定义它的两个子类:电视机和电脑,再定义一个判定类判定在程序动态运行时是哪台电器在运行,代码如下:
程序输出结果为:
电脑通电,编写程序
电视机通电,看电视
动态绑定的优点是当需要扩展程序功能,添加新的类时,不需要修改原来已经存在的类结构,只需要增加新的类即可。例如,如果要增加冰箱类,只需要重写电器类的support方法即可,代码如下:
在上面的例子代码中,程序又增加了Icebox类,Icebox类重写了父类的support()方法。重修修改TestEquipment代码如下:
由上面的代码可以看出,动态绑定可以很容易扩展程序功能,而无需改动原有的代码。
■ 知识点拨
多态和动态绑定实际上是让“做什么”和“怎么做”分离了,本文中的家用电器类(Equipment)只负责基础通电功能(support),而(support)的具体实现由电视(ColorTv)、电脑(Computer)、冰箱(Icebox)子类负责。因此,只要电器类通电,则其电视、电脑、冰箱就开始运行,至于运行的内容,则有电视、电脑、冰箱内部负责。■ 思考与练习
应用eclipse开发工具建立Equipment项目,实现教材内容中的代码案例,体会动态绑定的用法。