Java构造器内部的多态方法的行为

在一般的方法内部,动态绑定的调用是在运行时才决定的,因为对象无法知道它是属于方法所在的那个类,还是属于那个类的导出类。如果要调用构造器内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义。但是这个调用的效果可能很难预料,因为被覆盖的方法在对象被完全构造之前就会被调用。而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方法,不会产生多态。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值