美文网首页架构算法设计模式和编程理论程序员
使用多态的情况下初始化全过程

使用多态的情况下初始化全过程

作者: 重山杨 | 来源:发表于2017-01-15 18:03 被阅读0次

    在基类的构造器中要尽量避免调用可能被继承重写的方法,否则在初始化时将会引发意外

    一个动态绑定的方法调用会深入到继承层次的结构中,它可以调用导出类中的方法,如果在基类的构造器中这样做,就可能会调用某个方法,而这个方法所操纵的成员可能还未进行初始化:

    class Glyph{
        void draw(){
            print("Glyph.draw()");   //这个方法其实并未被调用
        }
        Glyph{
            print("Glyph() bfore draw()");
            draw();     //就是在这个地方,调用了可能在导出类中重写的方法,将可能导致意外结果
            print("Glyph() after draw()");
        }
    }
    
    class RoundGlyph extends Glyph{
        private int radius = 1;
        RoundGlyph(int r){
            radius = r;
            print("RoundGlyph.RounGlyph(), radius=" + radius);
        }
        void draw(){
            print("RoundGlyph.draw(), radius = "+ radius);   //基类在构造时实际调用的是此方法
        }
    }
    
    public class Test(){
        public static void main(String[] args){
            new RoundGlyph(5);      //初始化过程会先调用基类的构造器,基类初始化完成后才会进行导出类的初始化
        }
    }
    
    /*
    output:
    Glyph() before draw()     
    RoundGlyph.draw(), radius = 0     //调用了导出类中的方法,但相关参数在子类中,还未初始化
    Glyph() after draw()
    RoundGlyph.RounGlyph(), radius= 5  //最后才是进行导出类的初始化
    */
    

    在使用继承以及多态时的初始化过程:

    1)在任何事件发生之前,将分配给对象的存储空间初始化成二进制的零
    
    2)调用基类构造器。如果此时调用了被重写的方法,用于步骤一的缘故,方法中使用的变量值为0
    
    3)按照声明的顺序调用成员的初始化方法
    
    4)调用导出类的构造器主体
    
    

    注: 若导出类中的方法通过“组合”方式嵌入了一个类内部的对象的引用,其值就是null

    总结:


    在编写构造器时,需要尽可能用简单的方法使对象进入正常状态,尽量避免调用其他方法。

    在构造器中能够安全调用的只有基类中的final方法(也适用于private方法,它们自动属于final方法)。这些方法不能被覆盖,因此才是安全的。


    相关文章

      网友评论

        本文标题:使用多态的情况下初始化全过程

        本文链接:https://www.haomeiwen.com/subject/hlxubttx.html