有关类的继承的内容大概其就这么多了。之前提过了对象的构造以及初始化。现在在类的继承的基础上,继续来说对象的构造以及初始化,主要讨论子类如何完成继承父类的初始化。
当调用类的构造器来创建对象时,它将给新建的对象分配内存,并对对象进行初始化操作。
现在我们来探讨对对象进行初始化操作时候的细节。
对象的初始化操作将递归如下的步骤来进行:
1.设置实例变量的值为缺省的初始值 (0, false, null),不同的数据类型有不同的初始值。
2.调用类的构造器 (但是还没有执行构造方法体),绑定构造器参数。
3.如果构造器中有this()调用,则根据this()调用的参数调用相应的重载构造器,然后,转到步骤5;否则转到步骤4。
4.除java.lang.Object类外,调用父类的中的初始化块初始化父类的属性,然后调用父类构造器,如果在构造器中有super()调用,则根据super()中的参数调用父类中相应的构造器。
5.使用初始化程序和初始化块初始化成员。
6.执行构造器方法体中其他语句。
所谓的初始化块,就是我们前面提到的所谓“游离块”。不管使用哪个构造器创建对象,它都会被首先运行,然后才是构造器的主体部分被执行。
我们来看一个例子:
class Person {
private String name;
private int age;
private String sex;
public Person() {
System.out.println("构造器Person()被调用");
sex = "Male";
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
public Person(String theName) {
// 调用构造器Person()
this();
System.out.println("构造器Person(String theName)被调用");
name = theName;
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
public Person(String theName, int theAge) {
// 调用构造器Person(String theName)
this(theName);
System.out.println("构造器Person(String theName,int theAge)被调用");
age = theAge;
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
// 初始化块
{
name = "Tony Blair";
age = 50;
sex = "Female";
System.out.println("初始化块执行后:name=" + name + " ,age="
+ age + " ,sex=" + sex);
}
}
public class TestPerson {
public static void main(String[] args) {
Person person = new Person();
}
}
编译执行上面的程序,将会得到如下的输出:
初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person()被调用
name=Tony Blair ,age=50 ,sex=Male
可以看到,初始化块会先于构造器调用执行。读者可以将main()方法中调用的创建Person对象的构造器换成其他两个,在观察它的结果。同样可以得出上面的结论。
提示:初始化块的机制并不是必须的,你完全可以将属性的初始化和属性的声明结合在一起,如: String name = "Tony Blair";
下面我们看一个对象初始化的例子,以加深对对象初始化的理解。
class Person {
private String name;
private int age;
private String sex;
public Person() {
System.out.println("构造器Person()被调用");
sex = "Male";
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
public Person(String theName) {
System.out.println("构造器Person(String theName)被调用");
name = theName;
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
public Person(String theName, int theAge) {
System.out.println("构造器Person(String theName,int theAge)被调用");
name = theName;
age = theAge;
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
// 初始化块
{
name = "Tony Blair";
age = 50;
sex = "Female";
System.out.println("Person初始化块执行后:name=" + name + " ,age="
+ age + " ,sex=" + sex);
}
}
这里定义了一个父类Person,它里面定义了三个构造器以及一个初始化块。
我们再来定义一个Person类的子类Teacher,如下:
class Teacher extends Person {
// 部门
String department;
// 教龄
int schoolAge;
public Teacher() {
System.out.println("构造器Teacher()被调用");
}
public Teacher(String name) {
// 调用父类中的构造器Person(String theName)
super(name);
System.out.println("构造器Teacher(String name)被调用");
}
public Teacher(int theSchoolAge) {
schoolAge = theSchoolAge;
}
public Teacher(String dept, int theSchoolAge) {
// 调用本类中重载的构造器Teacher(int theSchoolAge)
this(theSchoolAge);
department = dept;
}
// 初始化块
{
department = "教务部";
System.out.println("Teacher初始化块执行后:name=" + name + " ,age=" + age
+ " ,sex=" + sex);
}
}
这个类中定义了四个构造器:一个不带参数的构造器;一个带一个String数据类型参数的构造器,它通过super()显式调用父类的构造器;一个带一个int数据类型参数的构造器;一个带两个参数的构造器,通过this()来调用类中带int类型参数的构造器。
public class TestInit {
public static void main(String[] args) {
System.out.println("------------------------------------");
Teacher t1 = new Teacher();
System.out.println("");
System.out.println("------------------------------------");
Teacher t2 = new Teacher("Tom");
System.out.println("");
System.out.println("------------------------------------");
Teacher t3 = new Teacher("财务部", 20);
}
}
这个程序通过三种构造器来创建三个Teacher对象,因为调用的构造器不同,所以对象初始化的步骤也有所不同。因为在这几个程序中,在几个关键部分都已经有信息打印到控制台,所以,只要执行这个程序,就可以看出各个调用构造器创建对象的运行细节。
编译并运行TestInit,可以在控制台上得到如下的信息:
------------------------------------
Person初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person()被调用
name=Tony Blair ,age=50 ,sex=Male
Teacher初始化块执行后:name=Tony Blair ,age=50 ,sex=Male
构造器Teacher()被调用
------------------------------------
Person初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person(String theName)被调用
name=Tom ,age=50 ,sex=Female
Teacher初始化块执行后:name=Tom ,age=50 ,sex=Female
构造器Teacher(String name)被调用
------------------------------------
Person初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person()被调用
name=Tony Blair ,age=50 ,sex=Male
Teacher初始化块执行后:name=Tony Blair ,age=50 ,sex=Male
相关推荐
构造函数初始化列表是C++中一个非常重要的特性,它允许程序员在对象创建时直接对类中的成员进行初始化,而不是先分配内存再赋值,这在效率和安全性上都有显著优势。 #### 构造函数初始化列表的作用与语法 构造函数...
本系列教程的课程安排参考了多本.net 1.1以及在目前的2.0新书的基础上认真编订。不敢夸口本系列多了不起,但至少敢保证你看完本系列,再做完每个小结的测试,你入门是绝对没有问题的!做一个简单的网站是绝对可以的!祝愿...
天轰穿系列教程之-16利用构造函数初始化对象天轰穿系列教程之-16利用构造函数初始化对象天轰穿系列教程之-16利用构造函数初始化对象天轰穿系列教程之-16利用构造函数初始化对象天轰穿系列教程之-16利用构造函数初始...
Java中的对象初始化流程是编程实践中一个非常重要的概念,它涉及到类加载、静态初始化块、实例初始化块、构造器等多个方面。下面将详细解释这个过程。 首先,对象初始化流程的起点是程序的入口点,即`main`方法。当...
### WPF 对象初始化器详解 #### 一、对象初始化器概述 对象初始化器是C# 3.0引入的一项新特性,它简化了对象创建的过程。在传统的面向对象编程中,创建对象后通常需要手动设置各个属性。这种方式不仅繁琐,而且...
1. 对象初始化——构造方法 2. 对象初始化——`@PostConstruct`注解的方法 3. 对象初始化——实现了`InitializingBean`接口的`afterPropertiesSet`方法 4. 对象初始化——自定义的`init`方法 5. ---容器启动完毕后.....
"C++ 子类构造函数初始化及父类构造初始化的使用" C++ 中的构造函数初始化是指在类对象创建时对其进行初始化的过程。构造函数是类的特殊成员函数,用于初始化类对象。在 C++ 中,子类构造函数的初始化涉及到父类...
在C++中,对象初始化的方法多种多样,包括直接初始化、复制初始化以及针对内置类型和类类型的特定方式。 对于内置类型,C++提供了三种初始化方式: 1. **空初始化**:不提供初始值,例如`int i;`或`new int;`。在...
- **初始化对象**:通过构造器初始化新创建的对象,设置其初始状态。 - **赋值**:最后,将创建好的对象的引用赋给之前声明的引用变量。 例如,下面的代码展示了如何创建一个`A`类的对象: ```java A a1 = new A()...
这是因为在每个构造函数开始时,都会隐式地调用对象初始化块。 **比较与结合** 静态初始化块和对象初始化块的执行顺序不同。静态初始化块在类加载时执行,而对象初始化块在创建新对象时执行。它们可以相互配合,以...
在C++编程中,构造函数是一种特殊的成员函数,它的主要任务是初始化类的对象。构造函数的初始化表达式是创建对象时执行的关键步骤,用于设置新对象的状态。在第14章“构造函数的初始化表达式”中,我们将深入探讨这...
在C++编程语言中,对象初始化是一个至关重要的过程,它涉及到类的实例化以及成员变量的赋初值。本文将深入探讨基于构造函数的对象初始化方法,以帮助开发者更好地理解和运用这一核心概念。 构造函数是C++中一种特殊...
本文将深入探讨C++构造函数中的初始化,包括传统的赋值方式、括号赋值、冒号初始化(也称为成员初始化列表)以及函数体初始化。 首先,C++中存在两种初始化方式:赋值运算符赋值和括号赋值。例如: ```cpp int a =...
在Java编程语言中,程序初始化的顺序是一个关键概念,它涉及到类加载、对象创建以及执行流程的安排。了解这些顺序对于编写高效、无错误的代码至关重要。以下是对Java程序初始化顺序的详细说明: 1. **类加载阶段**...
总结,这个压缩包文件提供了关于Java中类和对象初始化的实例,包括静态和非静态成员的处理、继承、构造函数的调用顺序等。通过分析并运行这些代码,开发者可以更深入地理解Java的初始化机制。对于初学者来说,这是一...
总结来说,C++对象构造的顺序是: 1. 按照声明顺序初始化成员对象的构造函数。 2. 调用基类的构造函数(如果有的话)。 3. 执行派生类构造函数的主体部分,初始化派生类特有的成员。 这个顺序保证了对象的构造过程...
在C++中,构造函数是一种特殊类型的成员函数,它在创建对象时自动调用,用于初始化对象的状态。默认构造函数是指没有参数的构造函数,它的作用是当创建对象时,如果没有提供任何初始值,就使用默认值来设置对象的...
类的初始化涉及到多个方面,包括静态成员变量、实例成员变量、静态初始化块、实例初始化块以及构造函数等。本文将详细探讨Java中类的初始化过程及其顺序,并通过具体的代码示例来帮助理解这一过程。 #### 二、基础...
本节主要讨论了Java中的构造器、成员初始化、对象创建过程、垃圾回收以及垃圾回收器的工作原理。 4.1 构造器 构造器是Java中用于初始化新创建对象的特殊方法。它的名字与类名完全相同,没有返回类型,且不能声明为...