Java中,父类和子类的构造顺序和时机
来源:互联网 发布:千里眼视频监控软件 编辑:程序博客网 时间:2024/04/28 11:53
下面是一个完整的测试类:
/**
* @(#)TestJava.java 2008-2-22
*
* Copyright 2007 GeneralData, Inc. All rights reserved.
*/
package com.bbebfe;
/**
* 这个类测试父类和子类的构造时机
* 父类中有一个(抽象)方法prt();
* 子类(实现)覆盖了这个方法,并打印"in child" + i,i是
* 子类中定义的一个成员字段,设定初值为10。
*
* 在父类的构造中调用prt(),
* 如果能够调用成功,说明子类对象在子类的构造方法执行前
* 已经在内存中构造好了(因为父类的构造方法会在子类的构造
* 方法前执行),因为如果子类对象没有在内存中存在,则
* 不可能执行打印,更不能打印成员字段i。
*
* 最终的执行结果是成功打印"in child 0",说明能够执行打印,
* 说明子类对象的内存已经分配。
* 但i的值打印为0,说明内存虽然已经分配,但成员字段尚未执行显示初始化,
* 默认初始化为0。
* 在Child的构造中打印i的值为10,说明成员字段的显示初始化在内存分配
* 和构造体之间进行。
*
* 因此可以看出一个Java对象的具体构造过程(不包含静态结构):
* 1. 父类对象内存分配
* 2. 父类字段默认初始化
* 3. 子类对象内存分配
* 4. 子类字段默认初始化
* 5. 进入父类构造-> 父类成员显示初始化(定义字段时设置的字段初值)
* -> 执行父类构造体(此时可以调用抽象方法,所有父类字段已初始
* 化完毕,但子类字段尚未进行显示初始化)
* 6. 进入子类构造-> 子类成员显示初始化(定义字段时设置的字段初值)
* -> 执行子类构造体(此时所有字段已经显示初始化)
*
* 因此,父类的构造中可以调用抽象方法(子类实现),但最好
* 不要这样做,因为子类对象仅仅分配了内存和默认初始化,还没有
* 进行显示初始化。
* @project TestJava
* @author chenhao
* @version 1.0.0, 2008-2-22
*/
public class TestJava {
public static void main(String[] args) {
Child c = new Child();
}
}
class Child extends Father
{
int i = 10;
/**
* 这个构造方法是没有必要写的,因为默认构造
* 肯定是按这个顺序执行的。但为了表示明确的
* 目的,因此把这个默认构造写出来
*
*/
public Child() {
super();
System.out.println(i);
}
@Override
public void prt() {
System.out.println("in child i = " + i + " k = " + k);
}
}
abstract class Father
{
protected int k = 5;
public Father() {
prt();
}
public void prt() {
System.out.println("in Father k = " + k);
}
}
* @(#)TestJava.java 2008-2-22
*
* Copyright 2007 GeneralData, Inc. All rights reserved.
*/
package com.bbebfe;
/**
* 这个类测试父类和子类的构造时机
* 父类中有一个(抽象)方法prt();
* 子类(实现)覆盖了这个方法,并打印"in child" + i,i是
* 子类中定义的一个成员字段,设定初值为10。
*
* 在父类的构造中调用prt(),
* 如果能够调用成功,说明子类对象在子类的构造方法执行前
* 已经在内存中构造好了(因为父类的构造方法会在子类的构造
* 方法前执行),因为如果子类对象没有在内存中存在,则
* 不可能执行打印,更不能打印成员字段i。
*
* 最终的执行结果是成功打印"in child 0",说明能够执行打印,
* 说明子类对象的内存已经分配。
* 但i的值打印为0,说明内存虽然已经分配,但成员字段尚未执行显示初始化,
* 默认初始化为0。
* 在Child的构造中打印i的值为10,说明成员字段的显示初始化在内存分配
* 和构造体之间进行。
*
* 因此可以看出一个Java对象的具体构造过程(不包含静态结构):
* 1. 父类对象内存分配
* 2. 父类字段默认初始化
* 3. 子类对象内存分配
* 4. 子类字段默认初始化
* 5. 进入父类构造-> 父类成员显示初始化(定义字段时设置的字段初值)
* -> 执行父类构造体(此时可以调用抽象方法,所有父类字段已初始
* 化完毕,但子类字段尚未进行显示初始化)
* 6. 进入子类构造-> 子类成员显示初始化(定义字段时设置的字段初值)
* -> 执行子类构造体(此时所有字段已经显示初始化)
*
* 因此,父类的构造中可以调用抽象方法(子类实现),但最好
* 不要这样做,因为子类对象仅仅分配了内存和默认初始化,还没有
* 进行显示初始化。
* @project TestJava
* @author chenhao
* @version 1.0.0, 2008-2-22
*/
public class TestJava {
public static void main(String[] args) {
Child c = new Child();
}
}
class Child extends Father
{
int i = 10;
/**
* 这个构造方法是没有必要写的,因为默认构造
* 肯定是按这个顺序执行的。但为了表示明确的
* 目的,因此把这个默认构造写出来
*
*/
public Child() {
super();
System.out.println(i);
}
@Override
public void prt() {
System.out.println("in child i = " + i + " k = " + k);
}
}
abstract class Father
{
protected int k = 5;
public Father() {
prt();
}
public void prt() {
System.out.println("in Father k = " + k);
}
}
- Java中,父类和子类的构造顺序和时机
- Java中子类和父类的构造函数?
- Java中子类和父类构造方法的问题
- 关于JAVA中子类和父类的构造方法
- Java中子类和父类的实例化顺序
- java中 静态成员、实例成员、构造方法在子类和父类中的执行顺序
- java父类子类中静态块非静态块构造方法的执行顺序和继承
- Java类中子类和基类的构造代码块,静态代码块、子类构造函数,基类构造函数的执行顺序
- 父类子类中代码块和构造函数的执行顺序
- C++中子类继承父类构造器和析构器的执行顺序
- c++ 中子类与父类构造析构的调用和顺序
- 子类和父类的 static块 和 构造方法 构造块 的执行顺序
- C++子类构造和析构被时,父类构造和析构的调用顺序
- 关于子类对象的构造函数和父类构造函数的执行顺序
- java 父类和子类构造器
- 继承中子类和父类构造方法的关系
- 继承中,父类与子类都有静态代码块和构造函数的时执行顺序
- java-父类和子类的构造函数
- Struts2与Struts1的对比
- 第一次交辞职报告!
- 用友成中国首家微软全球独立软件开发商
- 有关TI DAvinci 芯片的比较
- 扩展嵌入软件业务 微软在德国建立研发中心
- Java中,父类和子类的构造顺序和时机
- LoadImage()的使用
- 面对web并发访问时候,可能会产生这样的问题,你是怎么设计的
- tar 命令
- 熊全淹
- 2008年离岸外包五大预测
- Shell插入排序
- 搜索引擎技术核心揭密
- PDA项目 SQL CE 数据库注意事项