4.6.1 重载
Employee.java
运行结果:
多个构造器或多个方法采用相同的名字唯一区别是每个构造器或方法指定的参数类型或参数个数不同。这种特征就叫做重载。
4.6.2 默认域初始化
在构造器中没有给域赋初值,则会自动被赋值:数值为0、布尔值为flase、引用值为null。
4.6.3 默认构造器
当且仅当类中没有提供任何一个构造器时,才会自动生成一个默认的构造器。
4.6.4 显示域初始化
1、在类定义中直接将一个值赋给任何域。例如:
class Employee {
....
private String name = "..."
}
这种方法适用于当一个类中所有构造器都希望把相同的值赋给某个特定实例域。
2、初始值不一定是常量。可以调用方法对域进行初始化。例如:
class Employee {
...
static int assignId() {
int r = nextId;
nextId++;
return r;
}
...
private int id = assingnId();
}
6.6.5 参数名
有三种常见命名法:
1、用单个字符命名:
public Employee(String n, double s) {
name = n;
salary = s;
}
缺陷:只有阅读代码通过上下文才能理解参数n和s的含义。
2、每个参数前加a:
public Employee(String aName, double aSalary) {
name = aName;
salary = aSalary;
}
推荐使用这种命名法,每个读者一眼就知道每个参数的含义。
3、使用this指示隐式参数,也就是被构造的对象:
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
4.6.6 调用另一个构造器
关键字this除了引用方法的隐式参数外,还有另一个含义:
构造器的第一个语句形如this(...),这个构造器将调用同类的另一个构造器。
public Employee(double aSalary) {
//调用Employee(String,double)
this("Employee #" + nextId, aSalary);
nextId++;
}
解读:当调用new Employee(6000)时,Employee(double)构造器将调用Employee(String double)构造器。
4.6.7 初始化块
之前已经学了两种初始化数据域的方法:
1)在构造器中赋值
2)在声明中赋值
第三种是初始化块,这种机制不是必须的也不常用,所以略过。常用的是第一种:在构造器中初始化数据域。
总结调用构造器的处理步骤:
1)所有数据域被初始化为默认值;
2)按照声明中的顺序依次执行域初始化语句和初始化快;
3)如果构造器的第一句调用了第二个构造器,则执行第二个构造器主体;
4)执行构造器主体
本节源代码展示:例4-5
1)重载构造器
2)用this(...)调用另一个构造器
3)默认构造器
4)对象初始化块
5)静态域初始化块
6)实例域初始化
ConstructorTest.java
package com.vincent.javacore.constructortest;
public class ConstructorTest {
public static void main(String[] args) {
Employee[] staff = new Employee[3];
staff[0] = new Employee("Harry", 4000);
staff[1] = new Employee(6000);
staff[2] = new Employee();
for (Employee e : staff)
System.out.println("name: " + e.getName()
+ ", id: " + e.getId()
+ ", salary: " + e.getSalary());
}
}
Employee.java
package com.vincent.javacore.constructortest;
import java.util.Random;
public class Employee {
private static int nextId;
private int id;
private String name = "";
private double salary;
//三个重载构造器
public Employee(String aName, double aSalary) {
name = aName;
salary = aSalary;
}
public Employee(double aSalary) {
//调用Employee(String, double)构造器
this("Employee #" + nextId, aSalary);
}
//不会执行的构造器
public Employee() {
//初始化为默认值
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public int getId() {
return id;
}
static {
//构造一个新的随机数生成器
Random generator = new Random();
//nextId在0~9999中随机产生
nextId = generator.nextInt(10000);
}
//初始化域块
{
id = nextId;
nextId++;
}
}
运行结果:
name: Harry, id: 4070, salary: 4000.0
name: Employee #4071, id: 4071, salary: 6000.0
name: , id: 4072, salary: 0.0
name: Employee #4071, id: 4071, salary: 6000.0
name: , id: 4072, salary: 0.0