OOP 多态和构造器执行顺序

来源:互联网 发布:人工智能生活中的应用 编辑:程序博客网 时间:2024/05/22 15:53

OOP 多态和构造器执行顺序


在java的面试题中,对象的初始化顺序配合多态是一种常见考题!今天我就来详细的回顾一下!

类中一般包括这几个部分:

  • 静态成员 包括静态的成员变量 静态代码块、
  • 非静态的成员变量
  • 构造函数 (其实也是一种静态方法,只不过static是隐式的)
  • 静态方法和非静态方法

Java尽力保证,所有变量在使用前都能得到恰当的初始化

方法的局部变量 java以编译时错误的形式来贯彻这种保证;而对于类的成员变量,如果是基本数据类型都保证会有一个默认值,如果是引用类型,未被初始化则会被赋值为Null!

静态成员—–>成员变量(相互之间按照定义顺序)—–>构造器等任何方法

初始化对象时,并不会执行静态方法。静态方法直接通过类名进行访问


对象的创建过程

以Dog类为例

1.即使没有显示的指定static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象(构造器可以看成静态方法),或者Dog的静态方法/静态域首次被访问时,java解释器必须查找类路径,以定位Dog.class文件

2.然后载入Dog.class,有关静态初始化的所有动作(静态成员变量 静态代码块)都会执行。因此,静态初始化只在class对象首次加载的时候进行一次

3.当用new Dog()创建对象的时候,首先在堆上为Dog对象分配足够的存储空间

4.这块存储空间将会被清零,这就自动的将Dog对象中的所有基本数据类型都设置为默认值,而引用则被设置为null

5.执行父类的构造函数,依次递归直到继承层级的根。首先执行根,然后是下一层导出类,直到最近父类

5.执行所有出现于成员变量定义处的初始化操作

6.执行构造器本体


构造器与多态

基类的构造器总是在导出类的构造过程中被调用,并且按照集成的层次逐渐向上链接,以使每个基类的构造器都得以调用!

对复杂对象调用构造器的顺序:

1.首先调用基类的构造器。这个步骤会反复递归下去,首先是构造这种层次结构的,然后是下一层的导出类,等等知道最底层的导出类,也就是最近父类

2.按照声明顺序调用成员的初始化方法

3.调用导出类构造器的本体


例子

  • SomeThing.java
package OOP;public class SomeThing {    public SomeThing() {        System.out.println("SomeThing 构造方法正在执行");    }}
  • Person.java
package OOP;public class Person extends SomeThing {    static{        System.out.println("Person 静态代码块正在执行");    }    public Person() {        System.out.println("Person 构造方法正在执行");    }    public void introduce(){        System.out.println("你好,我是一个Person");    }    //此方法只有Person有,未被覆盖    public void personShow(){        System.out.println("Welcome to Person's Show");    }    //静态方法    public static void SoLo(){        System.out.println("Person静态方法正在执行");    }}
  • Student.java
package OOP;public class Student extends Person {    //成员变量,声明处实例化    private StudentInfo info = new StudentInfo();    static {        System.out.println("Student 静态代码块正在执行");    }    public Student() {        System.out.println("Student 构造方法正在执行");    }    // 覆盖的方法    public void introduce() {        System.out.println("你好,我是一个Student");    }    public void studentShow() {        System.out.println("Welcome to Student's Show");    }}
  • StudentInfo.java
package OOP;public class StudentInfo {    public StudentInfo() {        System.out.println("正在执行 StudentInfo 构造器");    }}
  • OOPdemo.java
package OOP;public class OOPdemo {    public static void main(String[] args) {        //1.首先声明对象为Person类型,则Person中静态成员会被执行        //2.然后调用Student的构造函数,加载Student类,静态成员先执行        //3.调用Student的构造函数,默认先调用父类的构造函数,递归直到根        //4.调用Student的构造函数,先初始化Student的成员变量,基本类型赋默认值,        //引用类型未初始化赋值为NULL,有初始化操作则执行        //5.调用Student构造函数的本体        Person p=new Student();        System.out.println("p的类型---"+p);        //执行覆盖方法,执行子对象(实际对象)        p.introduce();        //执行父类方法,未覆盖        p.personShow();;        //因为是Person引用所以,student类中添加的方法,person对象不可见        //没有 p.studentShow()        ((Student)p).studentShow();    }}
  • 执行结果

这里写图片描述

0 0
原创粉丝点击