假如有两个类,如下:
class Life {
@Override
public String toString() {
return "life";
}
}
class Animal extends Life {
@Override
public String toString() {
return "animal";
}
}
Life 类和 Animal 类中都有 toString() 方法,如果发生下面的情况,会调用哪个 toString() 方法呢:
Life a = new Animal();
System.out.println(a.toString());
输出结果为:
animal
从结果看出,a 调用了 Animal 类中的 toString() 方法。
a 的声明类型是 Life ,a 被指向使用 new Animal() 创建的对象,所以 a 的实际类型应该为 Animal 。a 调用哪个 toString() 方法是由它的实际类型决定的。这就是动态绑定。
假设 Piggy 是 Pig 的子类,Pig 是 Animal 的子类,Animal 是 Life 的子类,而 Life 是 Object 的子类。如果对象 g 是类 Piggy 的实例,那么当你调用一个方法 m 时,JVM 会依次在类 Piggy 、Pig 、Animal 、Life 、Object 中寻找方法 m,直到找到一个方法 m 便会停止寻找,然后调用这个最先找到的方法。这就是动态绑定的工作机制。
下面是关于动态绑定机制的一个例子:
public class Test {
public static void main(String[] args) {
printString(new Piggy());
printString(new Pig());
printString(new Animal());
printString(new Life());
}
public static void printString(Life life) {
System.out.println(life.toString());
}
}
class Life {
}
class Animal extends Life {
@Override
public String toString() {
return "animal";
}
}
class Pig extends Animal {
@Override
public String toString() {
return "pig";
}
}
class Piggy extends Pig {
}
输出结果为:
pig
pig
animal
Life@15db9742
最后输出的 Life@15db9742 是 Object 类中 toString() 的返回结果。