动态绑定是Java多态的一种表现形式,指的是代码在执行期间而不是编译时判断引用对象的实际类型,并根据其实际的类型,调用其相应的方法。
举个例子,家用电器包含电视、电脑、冰箱等电器设备,我们可以把家用电器抽象为类(Equipment),电视(ColorTv)、电脑(Computer)、冰箱(Icebox)作为家用电器类的子类。家用电器类提供support()方法,表示家用电器已通电,但通电后,电视、电脑、冰箱有不同的表现形式,可以用重写父类support()方法的技术来解决这个问题。
在程序运行过程中,让Equipment类型的变量指向Equipment子类的对象引用,当调用support()方法时,Java虚拟机会根据其实际的实例对象,调用该实例对象的support()方法。这就是java 的动态绑定,动态绑定是“向上转型”。
对象的动态绑定需要满足如下条件:
(1)类与类之间有继承关系;
(2)子类重写了父类的方法;
(3)父类变量指向子类对象;
(4)父类变量调用重写的方法。
案例1:建立电器类(父类),然后分别建立电视机类(子类)和计算机类(子类)。再建立电器管理类,负责调度电器通电操作。最后建立测试类,体验动态绑定的效果。
在PCoreUnit1项目新建equipment包,在equipment包下新建Equipment类,代码如下:
package equipment;
/**
* @ClassName: Equipment
* @Description: 类的继承与对象的多态性(动态绑定)案例1
* @author 编程训练营
* @date
*
*/
public class Equipment {
// 通电操作
public void support()
{
System.out.println("通电功能!");
}
}Equipment类是电器类的父类,它提供了support()方法,用于电器的通电操作。它的子类需要重写该方法。
在equipment包下新建ColorTv类,该类继承Equipment类。代码如下:
package equipment;
/**
* @ClassName: ColorTv
* @Description: 类的继承与对象的多态性(动态绑定)案例1
* @author 编程训练营
* @date
*
*/
public class ColorTv extends Equipment {
//重写父类的support()方法
@Override
public void support()
{
System.out.println("电视机通电,看电视");
}
}ColorTv类是Equipment类的子类,该类重写了父类的support()方法。
在equipment包下新建Computer类,该类继承Equipment类。代码如下:
package equipment;
/**
* @ClassName: Computer
* @Description:类的继承与对象的多态性(动态绑定)案例1
* @author 编程训练营
* @date
*
*/
public class Computer extends Equipment {
//重写父类的support()方法
@Override
public void support()
{
System.out.println("电脑通电,编写程序");
}
}Computer类是Equipment类的子类,该类重写了父类的support()方法。
在equipment包下新建Discriminate类,该类是电器管理类,负责调度电器通电操作。代码如下:
package equipment;
/**
* @ClassName: Discriminate
* @Description: 类的继承与对象的多态性(动态绑定)案例1
* @author 编程训练营
* @date
*
*/
public class Discriminate {
// 通电操作,参数类型为Equipment
public void through(Equipment equi)
{
equi.support();
}
}Discriminate类提供了through()方法,用于电器类通电操作,传入参数类型是Equipment类型,该参数指向Equipment子类实例对象的引用。
在equipment包下新建EquipmentTest类,该类是测试类。代码如下:
public class EquipmentTest {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param @param args 参数
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// 实例化Discriminate对象
Discriminate dis = new Discriminate();
// 调用dis对象的through()方法,实例化Computer对象
dis.through(new Computer());
// 调用dis对象的through()方法,实例化ColorTv对象
dis.through(new ColorTv());
}
}EquipmentTest类是测试类,在EquipmentTest类的main()方法中,实例化Discriminate对象,并调用Discriminate对象的through()方法。through()方法需要传入Equipment类型的参数,传入的参数可以是Equipment子类实例对象的引用,这里采用了“向上转型”。
程序执行结果为:

动态绑定的优点是当需要扩展程序功能,添加新的类时,不需要修改原来已经存在的类结构,只需要增加新的类即可。
案例2:增加冰箱类。
在equipment包下新建Icebox类,该类继承Equipment类。代码如下:
package equipment;
/**
* @ClassName: Icebox
* @Description: 类的继承与对象的多态性(动态绑定)案例2
* @author 编程训练营
* @date
*
*/
public class Icebox extends Equipment {
//重写父类的support()方法
@Override
public void support()
{
System.out.println("冰箱通电,可以冰冻事物");
}
}Icebox类是新添加的冰箱电器类,该类重写了父类的support()方法。
在equipment包下新建EquipmentTest1类,该类是测试类,用于测试新增加的Icebox类。代码如下:
package equipment;
/**
* @ClassName: EquipmentTest1
* @Description:类的继承与对象的多态性(动态绑定)案例1
* @author 编程训练营
* @date
*
*/
public class EquipmentTest1 {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param @param args 参数
*
* @return void 返回类型 @throws
*/
public static void main(String[] args) {
// 实例化Discriminate对象
Discriminate dis = new Discriminate();
// 调用dis对象的through()方法,实例化Computer对象
dis.through(new Computer());
// 调用dis对象的through()方法,实例化ColorTv对象
dis.through(new ColorTv());
// 调用dis对象的through()方法,实例Icebox对象
dis.through(new Icebox());
}
}程序执行结果如下图所示:

由案例2可以看出,动态绑定可以很容易扩展程序功能,而无需改动原有的代码。
多态和动态绑定实际上是让“做什么”和“怎么做”分离了,本文中的家用电器类(Equipment)只负责基础通电功能(support),而(support)的具体实现由电视(ColorTv)、电脑(Computer)、冰箱(Icebox)子类负责。因此,只要电器类通电,则其电视、电脑、冰箱就开始运行,至于运行的内容,则有电视、电脑、冰箱内部负责。