关于子类实例化和初始化的不解与猜想

本文详细解析Java中子类继承父类的过程,重点讨论了变量初始化、构造器调用及子类如何继承父类非私有变量的机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注:问题已解决。子类继承了父类所有的变量与方法,只是JVM设置了访问权限,不让你使用罢了。


首先来看看下面这段代码:

public class Base {
    private int i=5;
    public Base(){
        System.out.println("I come from "+this.getClass()+"  i="+this.i);
        this.display();
    }
    public int getI(){
        return i;
    }
    public void display(){
        System.out.println(this.i);
    }
}

public class Sub extends Base {
    private int i=22;
    public Sub(){
        i=222;
    }
    public void display(){
        System.out.println("I come from "+this.getClass()+" i="+this.i);
    }
}

public class Test {
    public static void main(String[] args) {
        Sub sub=new Sub();
        System.out.println(sub.getI());
    }
}

打印结果为:

image

下面我们来分析一下:

在main函数中首先执行

Sub sub=new Sub();

这行代码。而这行代码须分解为两步:

step1:执行new关键字,在执行这个关键字的时候,有一个疑问:new出来的对象中是否包含了父类中的所有变量(包括私有变量);

step2:执行new后面的括号即初始化对象。从Java核心技术卷一P131种可知初始化数据的步骤为:

1、所有数据被初始化为默认值;

2、按照类声明中出现的次序,依次执行所有域的初始化语句和初始化块;

3、如果构造器第一行调用了第二个构造器,则执行第二个构造器主体;

4、执行这个构造器的主体。

我相信这绝对是一个非常简化版的执行过程了。因为作者这里根本没有提到何时,调用父类的构造器。

那我们现在就来细细分析这个初始化的过程(其实在这篇文章中也分析过了,只是也不是很完整)。

为例更清晰的看看初始化的过程我们使用javap工具看看一个简单的类的字节码:

类代码:

public class SimpleClass {
    {
        i=6;
    }
    private int i=0;
    public SimpleClass(){
        i=5;
    }
}
  1. 字节码为:

image

这下很清楚了。当对子类Sub初始化时,会首先调用其父类的构造函数,在这时子类Sub只有变量的声明,没有进行任何的赋值操作。jvm开始初始化父类Base:由上图可知,变量定义时赋值和初始化块中赋值在构造器中赋值之前进行。所以首先jvm执行Base中的i=5;此时Base中的被初始化为5了。然后执行构造函数中的语句(请分清构造器中的语句和构造器中的字节码)。接下来的执行见这篇文章

现在问题是,在Sub初始化进行完之后,Sub包含了父类的那些变量?是不是包含了父类中的所有变量。如果不是(在书上看到是继承了父类非私有的变量),那么执行main函数的这条语句:

System.out.println(sub.getI());

为什么会打印出5呢?因为sub对象中的i变量的值现在为222啊。

注:在李刚老师的《Java程序员基本功》书中看到,子类继承父类的非私有方法,只是将方法放进了自类中,该方法和该子类中其他方法的唯一区别就是多了一个super的标签。那么是不是就可以得出Sub子类中也把父类中的私有变量放到了自己的内存中了,只是我们无法访问而已。

记下疑点,以便慢慢解决……也希望大神们多多指点……

转载于:https://www.cnblogs.com/yaoyinglong/p/Java%e5%ad%90%e7%b1%bb%e5%ae%9e%e4%be%8b%e5%8c%96.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值