Java的动态绑定机制是OOP中一个非常核心的概念。要理解动态绑定需要从Java的对象和类说起。
当我们在创建一个类的时候,实际上就是在定义一种新的数据类型。类中可以包含属性和方法,基于这个类创建一个对象的时候,这个对象就有拥有该类所有的属性和方法。
在引出动态绑定的概念之前,可以先讲一个比喻:
想象一下,你是一个餐厅的老板,有一个菜单(类),上面有各种菜品的名称(方法名),这个菜单是给客人(程序)看的,客人可以根据菜单点菜(调用方法)。在你餐厅中,有几位不同的厨师(对象),他们各自擅长不同类型的菜品,比如专门做西餐的、专门做中餐的等等。
当客人点了一个菜时(在代码中调用一个方法时),虽然菜单上的菜名(方法名)是一样的,比如“特色炒面”,但实际上根据不同厨师的专长,这道菜的做法和口味可能会有很大的不同(不同对象的同名方法可能有不同的实现)。客人点菜的时候并不需要指定哪个厨师来做这道菜,他们只需要知道菜名。
在你的餐厅里(在程序运行时),根据厨师的不同,点同一个名字的菜可能得到完全不同的结果。这就是动态绑定的本质:直到客人点菜(直到程序运行到那一点),你才决定由哪个厨师来烹饪(由哪个对象的哪个具体实现来执行方法)。也就是说,虽然编译器在编译程序时知道有一个叫“特色炒面”的菜(一个叫做某方法的接口),但具体由哪个厨师做这道菜,只有在实际运行时才能确定。
这种机制使得你的餐厅(程序)非常灵活,能够应对不同客人的口味偏好(不同的使用场景),而且你可以随时增加新的厨师(添加新的类和方法实现),不需要改动菜单(不需要修改现有代码)。
这个例子还是很清晰生动的,可以对动态绑定有个初步的认识。
什么是动态绑定
动态绑定(也称为晚期绑定)是一种在运行时(而非编译时)确定对象方法调用所对应的代码的机制。这意味着 Java 运行时会根据对象的实际类型来决定应该调用哪个方法,即使这个调用是通过一个引用变量发生的,该变量的类型可能是当前对象类型的任何父类。
动态绑定的简单实现
动态绑定的工作原理主要是通过方法重写实现的。
举个例子:
// 父类
class Animal{
public void speak(){
System.out.println("动物发出声音");
}
}
// 子类1
class Dog extends Animal{
@Override
public void speak(){
System.out.println("狗发出声音");
}
}
// 子类2
class Cat extends Animal{
@Override
public void speak(){
System.out.println("猫发出声音");
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Dog();
animal.speak();
animal = new Cat();
animal.speak();
}
}
例子输出:
狗发出声音
猫发出声音
在例子中,当调用 myAnimal.speak()
时,尽管 myAnimal
的类型是 Animal
,但由于它实际指向 Dog
的一个实例,所以调用的是 Dog
类的 speak
方法。同样,接下来它指向 Cat
的一个实例,所以调用的是 Cat
类的 speak
方法。
动态绑定的好处
根据例子可以看出来,我们可以新增其他的子类并重写父类的方法,程序其他部分都不用任何修改就可以继续使用。
动态绑定细节
细究一下Java的动态绑定机制(非常重要)_基于运行时的动态绑定-CSDN博客
以上博客讲得很细致,就不班门弄斧了