浅谈父类和子类构造器

      今晚师弟问了问题,关于子类和父类构造器的问题,做个分析总结:

 

运行代码:

 

package 左旋转字符串;
 
 
public  class A {
    public void testabstract(){
        System.out.print("父类方法  ");
        System.out.println("i = "+i);
    }
    A(){       
        System.out.println("palace 1");
        testabstract();
    }
     
    public static void main(String[] args) {
        cc cc = new cc(); 
        System.out.println("palace 2");
        cc.testabstract();
    }
 
}
     
class cc extends A{
    private int i = 1;     
    public void testabstract(){
        System.out.print("子类方法  ");
        System.out.println("i = "+i);
    }
    cc(){                          
     
    }  
 
     
}

  

结果:
 
  
 
  
 
palace 1
子类方法  i = 0
palace 2
子类方法  i = 1
  
 
  
 
  
 
cc cc = new cc();

  

这段代码,是实例化cc这个类的对象,会调用到cc的构造器

 

执行cc构造器是这样一个过程:

          1.最开始会隐式调用父类的构造器,对父类的非静态域进行初始化,执行父类A的构造器的时候,也会调用父类的构造器也就是Object类的构造器(这里会一层层往上级调用其构造器,知道最顶层的Object后才一层层返回到cc的构造器中来)。

          2.在父类A的构造器中调用到testabstract();方法,这个方法是父类的还是子类的?这里涉及到多台,testabstract()  是等价于  this.testabstract(); this代表当前对象,虽然该方法是在父类构造器中调用的,但是父类构造器是被子类调用,所以归根结底,this代表的是cc的当前对象,而不是父类对象,所以父类中调用的testabstract()是子类的重写后的方法,运行结果证明了这点。

 

为什么同样调用了子类的testabstract()方法  在place1 和 place2 打印出来的结果不同呢?

      这点关系到构造器对变量初始化问题,在执行构造器前系统已经为整个对象申请了内存了,对象的成员变量已经申请到内存,但是还诶初始化,所以系统是赋默认值 int 的为 0,进入构造器的时候,第一件事是调用父类的构造器,此时i还没被赋值,其值仍然是0,父类构造器中调用到子类的方法,故输出的值是 0;

      而在place2 再去执行testabstract() 则能输入想要的结果1.因为初始化已经全部完毕了

 

posted @   chenchuangfeng  阅读(819)  评论(1编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示