书中说在运行时能够自动的选择适当的方法,称为动态绑定。
如果说,是下面这样的代码为什么不对呢:
```java
class A{
public void f(int a){
System.out.println("我是父类");
}
}
class B extends A{
@Override
public void f(int a){
System.out.println("我是子类");
}
public static void main(Strings[] args){
A a = new B();
a.f(0);
}
}
```
> 根据java核心技术的介绍,很容易想到这个输出的内容一定是“我是子类”,但是如果更改为下面的代码:
```java
class A{
public void f(int a){
System.out.println("我是父类");
}
}
class B extends A{
@Override
public void f(int a){
System.out.println("我是子类");
}
public void print(String s){
System.out.println(s);
}
public static void main(Strings[] args){
A a = new B();
a.print("0");
}
}
```
> 当调用print方法时,书中不是讲,虚拟机知道a实际引用的对象,所以会先去B类的方法表中找print方法,为什么这里是错的呢?其实我知道是错的,知道一个引用变量所能使用的方法是根据他的声明类型而不是真正的类型,但是在动态绑定中,为什么第一个是对的呢?
B继承了A 就像一个大圆(B)里面有一个小圆(A)。B里面的print方法,a是无法获取到的。你可以画两个圆 A 里面有一个方法f。在画一个大圆B他把A包住了,并且在A的外面自己有一个方法print。你想用a来调用print,很明显它是获取不到的。
虚拟机知道,但是编译器不知道啊