2-16
4.6对象构造
4.6.1重载
GergorianCalendar类有多个构造器。可以使用:
GergorianCalendar today = new GergorianCalendar();
或者
GergorianCalendar deadline = new GergorianCalendar(2009,Calendar.DECEMBER,31);
这种特征叫做重载(overloading)。如果多个方法(比如,GergorianCalendar构造器方法)有相同的名字,不同的参数,便产生了重载。
4.6.2 默认域初始化
如果在构造器中没有显式地给域赋予初值,那么就会被自动地赋为默认值:数值为0、布尔值为false, 对象引用为null。
4.6.3 默认构造器
所谓默认构造器是指没有参数的构造器。例如,Employee类的默认构造器:
public Employee () {
name = "";
salary= 0;
hireDay = new Date();
}
如果在编写一个类时没有编写构造器,那么系统就会提供一个默认构造器。这个默认构造器将所有的实例域设置为默认值。
于是,实例域中的数值型数据设置为0,布尔型数据设置为false,所有对象变量将设置为null.
如果类中提供了至少一个构造器,但是没有提供默认的构造器,则在构造对象时如果没有提供构造参数就会被视为不合法。
例如,Employee类提供了一个简单的构造器:
Employee(String name, double salary, int y, int m, int d)
对于这个类,构造默认的雇员属于不合法。也就是,调用
e=new Employee();
将会产生错误。
4.6.4 显式域初始化
由于类的构造器方法可以重载,所以可以采用多种形式设置类的实例域的初始状态。
确保不管怎么样调用构造器,每个实例域都可以被设置为一个有意义的初值。
可以在类定义中,直接将一个值赋给任何域,例如:
class Employee
{
...
private String name = "";
}
4.6.5 参数名
在编写很小的构造器时(这是十分常见的),常常在参数命名上出现错误。通常,参数用单个字符命名:
public Employee(Sting n, double s)
{
name = n;
salary = s;
}
但这样做有一个缺陷:只有阅读代码才能够了解参数n和参数s的含义。于是,有些程序员在每个参数前面加上一个前缀"a":
public Employee(String aName, double aSalary)
{
name = aName;
salary = aSalary;
}
这样很清晰。非常好理解。
还有一种常见的技巧,它基于这样的事实:参数变量用同样的名字将实例域屏蔽起来。例如,如果将参数命名为salary, salary将引用这个参数,
而不是实例域。但是可以采用this.salary的形式访问实例域。this 指示隐式参数,也就是被构造的对象。
public Employee(String name, double salary)
{
this.name = name;
this.salary = salary;
}
4.6.6 调用另一个构造器
关键字this引用方法的隐式参数。然而,这个关键字还有另外一个含义。
如果构造器的第一个语句形如this(...),这个构造器将调用同一个类的另一个构造器。下面
是一个典型的例子:
public Employee(double s)
{
//call Employee(String,double)
this("Employee #" + nextId,s);
nextId++;
}
当调用 new Employee(60000)时,Employee(double)构造器将调用Employee(String,double)构造器。
采用这种方法使用this关键字非常有用,这样对公共的构造器代码部分只编写一次就可以了。
这个不太懂,挖个坑~~
4.6.7
初始化块
前面已经讲过两种初始化数据域的方法。
*在构造器中设置值
*在声明中赋值
实际上,Java还有第三种机制,称为初始化(initialization block)。在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行。
例如:
class Employee
{
public Employee(String n, double s)
{
name = n;
salary =s;
}
public Employee()
{
name = "";
salary = 0;
}
...
private static int nextId;
private String name;
private double salary;
...
//object initialization block
{
id = nextId;
nextId++;
}
}
在这个示例中,无论使用哪个构造器构造对象,id域都在对象初始化块中被初始化。首先运行初始化块,然后才运行构造器的主体部分。
这种机制不是必须的,也不常见。通常,直接将初始化代码放在构造器中。
浙公网安备 33010602011771号