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(); }}
- 执行结果
- OOP 多态和构造器执行顺序
- static,构造器,执行顺序
- 初始化块和构造器的执行顺序问题
- 静态代码块和构造器的执行顺序
- 成员变量和构造函数执行顺序
- 成员变量和构造函数执行顺序
- java构造器的执行顺序
- C++多继承构造函数执行顺序
- 构造函数执行顺序
- 非静态数据域、静态数据域和构造器 执行顺序
- C++中子类继承父类构造器和析构器的执行顺序
- Java 父类,子类各自均有构造器和静态代码块 执行的顺序
- 静态块 和构造器在继承情况下执行顺序
- static块和构造函数的执行顺序
- static块和构造函数的执行顺序
- 构造函数和析构函数的执行顺序
- Java代码块和构造方法执行顺序问题
- java静态代码块和构造方法执行顺序
- Android封装SharedPreferences工具类
- 数据库实验NetMusicShop(一)
- [LeetCode] Insert Interval
- LintCode_O(1)检测2的幂次
- Android开发工程师必看面试题:(一)
- OOP 多态和构造器执行顺序
- 数据库实验NetMusicShop(二)
- css3选择器
- 使用NSUserDefault存储数据
- Android 总结
- AOJ 0118
- android 使用Shape绘制实用圆圈
- Android学习它山之石:开源学习网站整理
- istringstream、ostringstream、stringstream