在一般的方法内部,动态绑定的调用是在运行时才决定的,因为对象无法知道它是属于方法所在的那个类,还是属于那个类的导出类。如果要调用构造器内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义。但是这个调用的效果可能很难预料,因为被覆盖的方法在对象被完全构造之前就会被调用。而C++则会避免这个问题。
Java 例子:
package com.myjava.study;
class Glyph {
void draw() {
System.out.println("Glyph.draw()");
}
public Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
public RoundGlyph(int r) {
radius = r;
System.out.println("RoundGlyph(), radius = " + radius);
}
void draw() {
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class PloyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
输出结果:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph(), radius = 5
在调用构造函数之前,对象已经分配好空间,并进行了默认初始化。在基类的构造函数调用的draw方法实际上是导出类的draw方法,但是这个时候radius的值还是默认的初始值,而不是5。
而对于C++,多态不会在构造函数中体现,因为在基类构造过程中,使用的是基类自己的虚函数指针,导出类的虚函数指针还未生成,因此在基类的构造函数中只会调用自己的方法。
#include <iostream>
using namespace std;
class Glyph {
public:
Glyph() {
cout << "Glyph() before draw()" << endl;
draw();
cout << "Glyph() after draw()" << endl;
}
virtual void draw() {
cout << "Glyph.draw()" << endl;
}
};
class RoundGlyph : public Glyph {
public:
RoundGlyph(int r) {
radius = r;
cout << "RoundGlyph.RoundGlyph(), radius = " << radius << endl;
}
private:
int radius;
};
int main()
{
RoundGlyph roundGlyph(5);
return 0;
}
输出结果:
Glyph() before draw()
Glyph.draw()
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
在基类的构造方法中调用draw方法实际调用的就是基类自己的draw方法,不会产生多态。