在一个类中定义的方法如果同时满足以下三个条件,该方法称为构造方法,具体如下:
1、方法名与类名相同
2、在方法名的前面没有返回值类型的声明
3、在方法中不能使用return语句返回一个值接下来通过一个案例来演示如何在类中定义构造方法,如例程3-7所示。
例程3-7Example05.java
class Person {
// 下面是类的构造方法
public Person() {
System.out.println("无参的构造方法被调用了...");
}
}
public class Example05 {
public static void main(String[] args) {
Person p = new Person(); // 实例化Person 对象
}
}
运行结果如图3-9所示。
在例程3-7的Person类中定义了一个无参的构造方法Person()。从运行结果可以看出,Person类中无参的构造方法被调用了。这是因为第9行代码在实例化Person对象时会自动调用类的构造方法,“new Person()”语句的作用除了会实例化Person对象,还会调用构造方法Person()。
在一个类中除了定义无参的构造方法,还可以定义有参的构造方法,通过有参的构造方法就可以实现对属性的赋值。接下来对例程3-7进行改写,改写后的代码如例程3-8所示。
例程3-8Example06.java
class Person {
int age;
// 定义有参的构造方法
public Person(int a) {
age = a; // 为age属性赋值
}
public void speak() {
System.out.println("I am " + age + " years old.!");
}
}
public class Example06 {
public static void main(String[] args) {
Person p = new Person(20); // 实例化Person 对象
p.speak();
}
}
3-8的Person类中定义了有参的构造方法Person(int a)。第13行代码中的“new Person(20)”会在实例化对象的同时调用有参的构造方法,并传入了参数20。在构造方法Person(int a)中将20赋值给对象的age属性。通过运行结果可以看出,Person对象在调用speak()方法时,其age属性已经被赋值为20。
构造方法的重载
与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。在创建对象时,可以通过调用不同的构造方法来为不同的属性进行赋值。接下来通过一个案例来学习构造方法的重载,如例程3-9所示。
例程3-9Example07.java
/ 为name属性赋值
age = con_age; // 为age属性赋值
}
// 定义一个参数的构造方法
public Person(String con_name) {
name = con_name; // 为name属性赋值
}
public void speak() {
// 打印name和age的值
System.out.println("大家好,我叫" + name + ",我今年" + age + "岁!");
}
}
public class Example07 {
public static void main(String[] args) {
// 分别创建两个对象p1 和p2
Person p1 = new Person("陈杰");
Person p2 = new Person("李芳", 18);
// 通过对象p1 和p2 调用speak()方法
p1.speak();
p2.speak();
}
运行结果如图3-11所示。
例程3-9的Person类中定义了两个构造方法,它们构成了重载。在创建p1对象和p2对象时,根据传入参数的不同,分别调用不同的构造方法。从程序的运行结果可以看出,两个构造方法对属性赋值的情况是不一样的,其中一个参数的构造方法只针对name属性进行赋值,这时age属性的值为默认值0。
注意:
1、在Java中的每个类都至少有一个构造方法,如果在一个类中没有定义构造方法,系统会自动为这个类创建一个默认的构造方法,这个默认的构造方法没有参数,在其方法体中没有任何代码,即什么也不做。
下面程序中Person类的两种写法效果是完全一样的。
第一种写法:
class Person
{
}
第二种写法:
class Person {
public Person() {
}
}
对于第一种写法,类中虽然没有声明构造方法,但仍然可以用new Person()语句来创建Person类的实例对象。由于系统提供的构造方法往往不能满足需求,因此,我们可以自己在类中定义构造方法,一旦为该类定义了构造方法,系统就不再提供默认的构造方法了,具体代码如下所示。
class Person {
int age;
public Person(int x) {
age = x;
}
}
上面的Person类中定义了一个对成员变量赋初值的构造方法,该构造方法有一个参数,这时系统就不再提供默认的构造方法,接下来再编写一个测试程序调用上面的Person类,如例程3-10所示。
例程3-10Example08.java
public class Example08 {
public static void main(String[] args) {
Person p = new Person(); // 实例化Person 对象
}
}
编译程序报错,结果如图3-12所示。
从图中可以看出程序在编译时报错,其原因是调用new Person()创建Person类的实例对象时,需要调用无参的构造方法,而我们并没有定义无参的构造方法,只是定义了一个有参的构造方法,系统将不再自动生成无参的构造方法。为了避免出现上面的错误,在一个类中如果定义了有参的构造方法,最好再定义一个无参的构造方法。
2、思考一下,声明构造方法时,可以使用private访问修饰符吗?下面就来运行一下例程3-11,看看会出现什么结果。
例程3-11Example09.java
class Person {
// 定义构造方法
private Person() {
System.out.println("调用无参的构造方法");
}
}
public class Example09 {
public static void main(String[] args) {
Person p = new Person();
}
}
图3-13运行结果
从图3-13中可以看出,程序在编译时出现了错误,错误提示为private关键字修饰的构造方法Person()只能在Person类中被访问。也就是说Person()构造方法是私有的,不可以被外界调用,也就无法在类的外部创建该类的实例对象。因此,为了方便实例化对象,构造方法通常会使用public来修饰。