- 创建子类对象的时候,并不会创建父类对象,但是会调用父类的构造函数,来完成对父类中“域”的初始化,只有这样,才能保证创建出来的对象的完整性。
- 其实更是为了多态,可以在不创建父类对象的情况下,子类对象的this指针,可以安全的调用父类中没有被重写的公开的方法。
public class Test{
private int weight;
public Test() {
System.out.println("Test:" + this);
}
public static void main(String[] args) {
Test test = new SubTest();
test.setWeight(34);
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
class SubTest extends Test{
public SubTest() {
System.out.println("SubTest:" + this);
}
}
上面的运行结果为:
分析:
- 由运行结果可知,传入到父类构造函数中this指针,其实就是子类对象的地址,并不是父类对象的地址,说明没有创建父类对象。
某S老师相关看法:
在我没有真正了解JVM是如何工作的情况下,我都任何看法都持怀疑的态度
- 问题一:子类没有继承父类的私有属性,但是继承的实例方法却调用了这个属性,怎么办?
答: 创建一个dog对象时,并没有创建父类对象,但是在堆中为父类的私有属性分配了空间;调用父类的构造方法需要某个父类的私有属性但是子类并没有继承到的时候,就会到在堆中父类动态绑定的私有属性空间里找到对应的属性,然后对该属性进行初始化。 - 创建一个子类对象的过程:
- 在堆中给子类对象开辟空间的时候,会先在对象空间中,给继承的属性开辟空间,然后在堆中给父类的私有属性开辟一个空间,并把这块空间跟父类绑定;再在堆中对象空间中开辟方法空间,把从父类继承的方法加载进去,再把子类的方法加载进去,如果子类有方法与从父类继承的方法 方法名和参数签名相同,那就覆盖了父类的该方法
在给子类对象属性设值的时候,会把子类的地址传给父类的构造方法,当调用父类的构造方法进行设值的时候,会找到跟父类动态绑定的私有属性,进行设值;再调用子类的构造方法为子类的属性设值; - 关于继承的内存图: