在java中,当创建一个子类对象会不会先创建父类对象?(如果父类是抽象类呢?)
被一些教材和资料误导和困扰,有些教材和资料上说,按照面向对象的思想,“没有爸爸,怎么会有儿子”,即 “没有父类怎么会有子类”。言外之意就是说,创建子类对象时,会先创建父类对象!然而真的是这样吗?
提个问题:如果当创建一个子类对象会先创建父类对象的话,那么如果父类是抽象类的话,那该抽象父类也会被实例化喽,这与抽象类不能实例化相互矛盾啊!
package javase5;
public abstract class Animal {
int age;
public Animal() {
this.age = 6;
System.out.println("我是Animal类的无参构造函数");
}
}
package javase5;
public class Cat extends Animal{
public Cat() {
// super();
//就算不写super();这行代码,系统也会默认自动调用父类的无参构造函数
System.out.println("我是Cat类的无参构造函数");
}
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.age);
}
}
1.产生对象,进行成员变量默认初始化。
整个对象是在一开始即被完整创建,其所有数据结构都已经分配内存。
以使得后续的代码能对这部分数据进行访问。
默认初始化,例如 private String str = null;
2.构造器形参赋值。
构造器也是方法,也需要接收参数。
3.检查构造器方法体第一行是否是 this(args...),若有则执行子类对应构造方法(回到步骤2)
同一个构造器中,3/4有且必有唯一一个
大部分时候super()未显示调用,但不显示指定this()则隐式调用super()
4.检查构造器方法体第一行是否是 super(args...),若有则执行父类对应构造方法(回到步骤2)
抽象类是有构造函数的,但不能通过new关键字调用。
抽象类的构造函数依然会执行,对其抽象类的数据进行访问或操作。
之后你仍然可以通过子类对象正确访问父类抽象类的属性或方法也是因为如此。
5.当前类的成员变量显示初始化。
类变量或类代码块会在类第一次被加载时执行,之后不再执行。
成员变量显示初始化,例如 private String str = "a";
代码块显示初始化,例如 {str = "b"};
6.执行当前构造方法中的代码块
若是步骤3/4执行到此,则最后子类继续步骤5
当子类执行6结束,整个对象的创建过程结束
关于通用的实例化
称呼,有两个用法区别,一是通过new创建对象,二是给类的属性赋值的流程。
So
属性
也会被实例化。创建子类对象,会默认先访问父类的无参构造方法,并不是先创建对象,所以先输出:我是Animal类的无参构造函数
父类是接口,其实需要的是该抽象类的子类对象,所以就会访问这个抽象类的实例化对象的无参构造方法
并不会创建父类对象,只是初始化,并且只初始化一次,服务器没有停,再次访问这个父类的子类,也不会再初始化,
如果每次创建子类,都要创建父类对象,那 Object 这个类只要运行都会创建了,这不科学