对比下面,在同样不使用虑函数的情况下,指向导出类的基类指针在调用导出类中重载了的方法时结果不同。
C++代码:
class A{
public:
void f1(){cout << "class A\n" ;}
};
class B :public A{
public:
void f1(){cout << "classB\n";}
};
void main() {
A *a = new B;
a -> f1();
delete a;
}
输出结果:
Class A
Java代码:
class A {
publicvoid show(){System.out.println("class a");}
}
class B extends A{
publicvoid show(){System.out.println("class b");}
}
publicclass Main {
publicstaticvoid main(String[] args) {
A a = new B();
a.show();
}
输出结果:
class b
如果使用了虚函数c++和java的结果一样。
产生以上差异是不同语言的绑定方式不同造成的。绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定。静态绑定可以理解为程序在编译期进行的绑定,而动态绑定指在运行时根据具体对象的类型进行绑定。
在java中只有final、static、private和构造方法是静态绑定的,其它所有方法都采用动态绑定。而c++中是进行的是静态绑定,只有虚函数进行的是动态绑定。所以c++中A类的指针只会调用A类的方法,虽然它指向的是一个B类的对象。而在java中虽然引用是A类的,但是由于动态绑定的关系,当通过方法名调用方法时,jvm会判断出当前对象的类型是B而不是A,所以会调用B类的中的相应方法。