首页 > 解决方案 > 不清楚动态绑定

问题描述

我不正确理解动态绑定和覆盖的概念:

这是一些代码:

class Cake {
    public void taste (Cake c) {
        System.out.println("In taste of Cake class");
    }
}

class ChocolateCake extends Cake {
    public void taste(Cake c) {
        System.out.println("In taste (Cake version) of ChocolateCake class");
    }
    public void taste(ChocolateCake cc) {
        System.out.println("In taste (ChocolateCake version) of ChocolateCake class");
    }
}


public static void main(String[] args)
{
    ChocolateCake cc = new ChocolateCake();
    Cake c = new ChocolateCake();
    Cake c1 = new Cake();
    Cake c2 = new ChocolateCake();

    c1.taste(cc);
    c1.taste(c);

    c2.taste(cc);
    c2.taste(c);
}

我期望:

In taste of Cake class
In taste of Cake class
In taste (ChocolateCake version) of ChocolateCake class" <----
In taste (Cake version) of ChocolateCake class

实际的:

In taste of Cake class
In taste of Cake class
In taste (Cake version) of ChocolateCake class <----
In taste (Cake version) of ChocolateCake class

如果对象是 ChocolateCake 类型并且我调用 cc 也是 ChocolateCake,编译器怎么会显示它正在获取 Cake 作为参数?

标签: java

解决方案


这是因为 Java 使用静态和动态绑定来选择在这种情况下调用的方法。

有问题的线是这个,对吧?

c2.taste(cc);

编译器首先选择调用哪个方法(静态绑定)。由于c2是 compile time type Cake,编译器只看到taste(Cake)方法。所以它说“呼叫taste(Cake)”。

现在在运行时,运行时需要taste(Cake)根据c2. 这是动态绑定。它会选择 中的那个Cake吗?还是里面的那个ChocolateCake?由于c2is 是运行时类型ChocolateCake,它调用taste(Cake)in的实现ChocolateCake

如您所见,您认为会调用的方法 - taste(ChocolateCake)- 甚至没有被提及!这是因为这是taste方法的不同重载,并且因为它在ChocolateCake类中,编译器看不到。为什么编译器看不到?因为c2是编译时类型Cake

简而言之,编译器决定哪个重载,运行时决定哪个实现。

回应您的陈述:

如果对象是 ChocolateCake 类型...

只有知道对象是 type ChocolateCake。编译器没有。它只知道c2是类型Cake,因为这就是它的声明所说的。


推荐阅读