构造方法的重载
与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。在创建对象时,可以通过调用不同的构造方法来为不同的属性进行赋值。接下来通过一个案例来学习构造方法的重载,如文件1所示。
文件1 Example10.java
1 class Person {
2 // 声明String类型的变量name
3 String name;
4 // 声明int类型的变量age
5 int age;
6 // 定义有参构造方法
7 public Person(int a) {
8 age = a; // 为age属性赋值
9 }
10 public Person(String n,int a){
11 name = n; // 为name属性赋值
12 age = a; // 为age属性赋值
13 }
14 // 定义 speak() 方法
15 public void speak() {
16 System.out.println("我今年" + age + "岁了!");
17 }
18 // 定义say()方法
19 public void say(){
20 System.out.println("我叫"+name+",今年" + age + "岁了!");
21 }
22 }
23 public class Example10 {
24 public static void main(String[] args) {
25 Person p1 = new Person(18);
26 Person p2 = new Person("张三",32);
27 p1.speak();
28 p2.say();
29 }
30 }
运行结果如图1所示。
图1 运行结果
文件1中,Person类中定义了两个构造方法,它们实现了方法的重载。在创建p1对象和p2对象时,根据传入参数个数的不同,分别调用了不同的构造方法。从图1可以看出,两个构造方法对属性赋值的情况是不一样的,其中p1对象只对age属性进行赋值,在调用speak()方法后,输出年龄信息;而p2对象对name和age属性进行赋值,在调用say()方法后,会输出姓名和年龄信息。
脚下留心
①在Java中的每个类都至少有一个构造方法,如果在一个类中没有显示地定义构造方法,系统会自动为这个类创建一个默认的构造方法,这个默认的构造方法没有参数,在其方法体中没有任何代码,即什么也不做。
下面程序中Person类的两种写法效果是完全一样的。
第一种写法:
class Person {
}
第二种写法:
class Person {
public Person() {
}
}
对于第一种写法,类中虽然没有显示地声明构造方法,但仍然可以用new Person()语句来创建Person类的实例对象。由于系统提供的无参构造方法往往不能满足需求,因此,可以自己在类中定义构造方法,一旦为该类定义了构造方法,系统将不再提供默认的无参构造方法。
如果将文件1中实例化p1对象时传入的参数18删除,会发现Eclipse中出现了构造器没有定义的错误提示,如图2所示。
图2 错误信息
从图2可以看出,程序提示“The constructor Person() is undefined”,即构造器Person()未定义。其原因是调用new Person()创建Person类的实例对象时,需要调用无参的构造方法,而Person类中已经定义了两个有参的构造方法,此时系统将不再提供无参的构造方法,所以Person类中没有无参的构造方法。为了避免出现上面的错误,在一个类中如果定义了有参的构造方法,最好再定义一个无参的构造方法。
②思考一下,声明构造方法时,可以使用private访问修饰符吗?下面就来测试一下,看看会出现什么结果。
将文件1中定义的第一个有参构造的修饰符public修改为private后,会发现Eclipse中又出现了一个错误,如图3所示。
图3 运行结果
从图3可以看出,Eclipse中的错误提示为“The constructor Person(int) is not visible”,即构造方法Person(int)不可见。出现此错误的原因是被private访问控制符修饰的构造方法Person(int)只能在当前Person类中被访问无法在类的外部被访问,也就无法通过该私有构造方法来创建对象。因此,为了方便实例化对象,构造方法通常会使用public来修饰。