原文:https://blog.csdn.net/qq_34343303/article/details/81612940
1.java中子类中是否有父类的私有成员属性?
需要明确,父类的私有成员是不能被子类继承的么为何在这里输出的是父类的值?
(2)还是说创建子类对象时同时
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
}
}
到这里,会有疑问
(1)若是a b没有被继承,那
创建了父类对象?
对于第一个问题:一开始就说了,父类私有的成员是不能被子类继承的
对于第二个问题,我们再来看看一下代码:
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所指向的空间为同一空间!(有人可能对hashCode() 方法返回的这一串数字不太理解,具体可参考https://blog.csdn.net/qq_34343303/article/details/81612819,你可以先理解为就是对象的地址)
解析:
其实我们在创建一个子类的时候,子类的所向指向的堆区中存放了子类自有的成员变量,同时还存放了父类所拥有的成员变量。
在创建一个子类的时候,我们把创建的时候的堆内存内存划分为两个区域,其中有一个super区,在这个区域中,存放的是父类的成员属性。另一个就是this区域,在这个区域存放的是子类自己的成员属性。
在方法区中,同样包括了两个部分,一个部分是super的方法区:super的方法区,只能指向父类的成员属性和方法,子类的是无法访问的。另一个是this的方法区,this的权限就相对大一些,可以访问子类自己的属性和方法,同时还可以访问父类的public的属性和方法(可继承的方法和属性)。
当子类在访问一个属性后者方法的时候,他首先会从this所指向的堆内存或者方法区寻找,如果找到了则执行,如果找不到,则要从super区中去寻找。这样理解覆盖就非常明了了,既是在子类中覆盖了父类的成员属性,然后输出,那么首先输出的就是子类的成员属性,不过父类中的成员属性同样存在。
附图