java中关于子类中是否有父类的私有成员属性的分析

来源:互联网 发布:电脑功率测试软件 编辑:程序博客网 时间:2024/06/12 23:00

问题描述:java中子类中是否有父类的私有成员属性?
问题解释
Sun粑粑很明确的告诉我们,类的私有成员变量是不可以被继承哒,我们去理解为父类的私有成员属性是不可能存在子类中的。但是当我们去创建一个父类的时候,在父类的构造其中我们调用了子类的构造器,那么此时在内存中是什么情况???难道在创建父类的同时,在父类中同时创建了一个子类?
例如:

class Father {    private int a = 1;    private int b = 1;    public int getA() {        return a;    }    public int getB() {        return b;    }}public class Son extends Father {    int b = 2;    int a = 2;    public static void main(String[] args) {        Son s = new Son();        System.out.println(s.getB()); // 输出1        System.out.println(s.getA()); // 输出1    }}
从输出的结果上我们可以很明显的看到,输出的a b都是父类中的私有成员属性的值,神马情况?若是a b没有被继承,那么为何在这里输出的是父类的值?若是a b有被继承,那么为何在子类中没有被重载?难道Java粑粑在逗我?在子类中创建了一个父类?

我们继续看一个例子

class Father {    public Father(){        System.out.println(this.hashCode());            //2018699554    }}public class Son extends Father {    public Son(){        System.out.println(this.hashCode());            //2018699554        System.out.println(super.hashCode());           //2018699554        System.out.println(super.equals(this));         //true    }    public static void main(String[] args) {        new Son();    }}

从这里我们可以看到,答案很明确,肯定不是在子类中同时创建了一个父类,hashcode和equals都是一样的,也就是说super和this所指向的空间为同一空间!

问题解析
其实我们在创建一个子类的时候,子类的所向指向的堆去区中存放了子类自有的成员变量,同时还存放了父类所拥有的成员变量。
在创建一个子类的时候,我们把创建的时候的堆内存内存划分为两个区域,其中有一个super区,在这个区域中,存放的是父类的成员属性。另一个就是this区域,在这个区域存放的是子类自己的成员属性。
在方法区中,同样包括了两个部分,一个部分是super的方法去,super的方法去,只能指向父类的成员属性和方法,子类的是无法访问的。另一个是this的方法去,this的权限就相对大一些,可以访问子类自己的属性和方法,同时还可以访问父类的public的属性和方法。
当子类在访问一个属性后者方法的时候,他首先会从this所指向的堆内存或者方法区寻找,如果找到了则执行,如果找不到,则要从super区中去寻找。这样理解覆盖就非常明了了,既是在子类中覆盖了父类的成员属性,然后输出,那么首先输出的就是子类的成员属性,不过父类中的成员属性同样存在。

总结
我们来打个比方,父亲和儿子。儿子长大要立家了,自己盖了一栋房子,可是儿子很孝顺,舍不得让父亲自己住,于是盖了一个二层的小别墅,一楼儿子自己住(也就是子类this内存空间)二楼父亲住(也就数super所指内存空间),盖楼了之后,儿子将父亲的东西统统一样不拉的搬到了小别墅的二楼(孝顺的孩子)父亲把自己和儿子公用的东西挂在了窗外(public)儿子可以使用,把自己私有的东西藏在屋内(private),儿子不可以动!
儿子在找东西的时候,首先会从自己的屋里去找,如果找不到,儿子再去窗外看看父亲那里有没有。但是父亲年级大了下楼不方便,用东西就只能在自己屋里找。
如果爷爷还活着,那么问题就来了,二层小楼不够用了,可能需要三层,四层…顶层住的是祖爷爷Object。

1 0
原创粉丝点击