构造器(构造方法)
Java构造方法是在实例化对象时调用的特殊方法。换句话说,当你使用new关键字时,构造方法初始化新创建的对象。
下面是一个简单的例子,它创建了一个对象,同时也调用了类构造方法
MyClass myClassObj = new MyClass();
这个例子创建一个新的MyClass对象,同时MyClass的无参数的构造方法会被调用。
Java类构造方法初始化该类的实例(对象)。通常,构造方法初始化那些需要被初始化的对象的字段。 Java构造方法也可以带参数,所以字段可以在创建时在对象中初始化。
定义一个构造方法
下面是一个简单的Java构造方法声明的例子。
public class MyClass {
public MyClass() {
}
}
其中构造方法是下面这一部分:
public MyClass() {
}
Java构造函数方法的第一部分是访问修饰符。访问修饰符的含义与方法和字段相同。他们确定哪些类可以访问(调用)构造方法。
Java构造方法声明的第二部分是构造方法所属类的名称。使用类名做为方法就是告诉Java编译器,该方法是一个构造方法。另外请注意构造方法没有返回类型。
Java构造方法声明的第三部分是构造方法可以使用的参数列表。构造方法参数在构造方法的类名部分之后的括号()中声明。在上面的构造方法声明示例中,没有声明参数。我将在本文稍后介绍一个带有参数的Java构造方法声明的例子。
Java构造方法声明的第四部分是构造方法的主体。构造方法的主体在参数列表后面的大括号{}内定义。在上面的构造方法示例中,构造方法体内没有任何操作。这是一个“空”的构造方法。
类可以有多个构造方法--构造方法重载
一个类可以有多个构造方法,只要它们的参数不一样就可以。你可以根据需要定义许多构造方法。当一个Java类包含多个构造方法时,我们说构造方法是重载的(有多个版本)。
下面是一个Java构造方法重载示例:
public class MyClass {
private int number = 0;
public MyClass() {
}
public MyClass(int theNumber) {
this.number = theNumber;
}
}
上面的Java类包含两个构造方法。第一个构造方法是一个无参数构造方法,意味着它不带参数。第二个构造方法接受一个int参数。在构造方法内部,int参数值被分配给一个字段,这意味着参数的值被复制到该字段中,该字段因此被初始化为给定的参数值。
字段名称(this.number)前面的关键字this不是必须的。只是告诉编译器它引用的是number字段。
默认的无参数构造方法
你可以不为类定义一个构造方法,但是如果不定义任何构造方法,Java编译器将为你插入一个默认的无参构造方法。因此,一旦类被编译,它总会至少有一个无参数的构造方法。
如果你为你的类定义了一个构造方法,那么Java编译器将不会在你的类中插入默认的无参构造方法。
构造方法参数
正如你已经看到的,Java构造方法可能需要参数。这些参数可以用来初始化新建对象的内部状态(字段)。下面是一个例子:
public class Employee {
private String firstName = null;
private String lastName = null;
private int birthYear = 0;
public Employee(String first,
String last,
int year ) {
firstName = first;
lastName = last;
birthYear = year;
}
}
在这个例子中,Java构造方法声明了三个参数:first,last和year。在构造方法体内部,这三个参数的值被分配给Employee对象的字段。
每个参数后面的换行符都是可选的后,Java编译器忽略这里的换行符。如果需要,也可以在单行中写入参数声明,如下所示:
public Employee(String first, String last, int year ) {
firstName = first;
lastName = last;
birthYear = year;
}
为了调用这个接收三个参数的构造方法,你需要像如下所示一样实例化Employee对象:
Employee employee = new Employee("Jack", "Daniels", 2000);
参数传递给构造方法。然后创建对象,并执行构造方法。执行上面的构造方法之后,由构造方法初始化的字段将包含参数传递的值。
Java构造方法参数可以与字段具有相同的名称。如果一个构造方法参数与一个字段具有相同的名称,那么Java编译器就会知道你引用了哪个参数。默认情况下,如果参数(或局部变量)与同一个类中的字段具有相同的名称,则该参数(或局部变量)会为该字段“影子”。看看这个构造方法:
public class Employee {
private String firstName = null;
private String lastName = null;
private int birthYear = 0;
public Employee(String firstName,
String lastName,
int birthYear ) {
firstName = firstName;
lastName = lastName;
birthYear = birthYear;
}
}
在Employee类的构造方法中,firstName,lastName和birthYear标识符现在引用是构造方法的参数,而不是具有相同名称的Employee字段。因此,构造方法现在只是将参数设置为等于它们自己的值。员工字段永远不会被初始化。
要向Java编译器发信号表示你指的是Employee类的字段而不是参数,请将this关键字加上.放在字段名称的前面。示例如下:
public class Employee {
private String firstName = null;
private String lastName = null;
private int birthYear = 0;
public Employee(String firstName,
String lastName,
int birthYear ) {
this.firstName = firstName;
this.lastName = lastName;
this.birthYear = birthYear;
}
}
这样做就能使员工的字段能够正确的初始化了。
调用一个构造方法
当你创建包含构造方法的类的实例时,你可以调用构造方法。
MyClass myClassVar = new MyClass();
这个例子调用了本文前面定义的MyClass的无参构造方法。
如果你想传递参数给构造方法,你需要在类名之后的括号之间加入参数,如下所示:
MyClass myClassVar = new MyClass(1975);
此示例将一个int参数传递给MyClass构造方法。
在一个构造方法中调用另一个构造方法
在Java中,可以在一个构造方法内部调用另外一个构造方法。在构造方法中调用另一个构造方法时,可以使用this关键字来引用构造方法。示例如下:
public class Employee {
private String firstName = null;
private String lastName = null;
private int birthYear = 0;
public Employee(String first,
String last,
int year ) {
firstName = first;
lastName = last;
birthYear = year;
}
public Employee(String first, String last){
this(first, last, -1);
}
}
注意第二个构造方法的定义。在构造方法体内部,你可以找到这个Java语句:
this(first, last, -1);
关键字this后跟括号和参数意味着在同一个Java类中的另一个构造方法将会被调用。被调用的其他构造方法取决于传递给构造方法的参数(在this关键字后面的括号内)。在这个例子中,它是调用的类中的第一个构造方法。
调用父类的构造方法
在Java中,一个类可以扩展另一个类。当一个类扩展另一个类时,也被称为继承。扩展的类称为子类,被扩展的类称为超类(父类)。
一个扩展另一个类的类不会继承它的构造方法。但是,子类必须在它其中一个的构造方法内中调用超类的一个构造方法!
看看下面的两个Java类。Car类继承自Vehicle类。
public class Vehicle {
private String regNo = null;
public Vehicle(String no) {
this.regNo = no;
}
}
public class Car extends Vehicle {
private String brand = null;
public Car(String br, String no) {
super(no);
this.brand = br;
}
}
注意Car类中的构造方法。它使用这个Java语句调用超类的构造方法:
super(no);
使用super关键字是指超类。当super关键字后面跟着括号时,就是指调用超类中的构造方法。在个例子中,它指的是Vehicle类中的构造方法。由于Car扩展了Vehicle,Car类的构造方法必须调用Vehicle中的一个构造方法。
构造方法的访问修饰符
构造方法的访问修饰符决定了允许调用该构造方法的类的范围。更多内容请参考访问修饰符章节。
例如,如果构造方法被声明为protected,则只有同一个包中的类或该类的子类才能调用该构造方法。
一个类可以有多个构造方法,每个构造方法可以有自己的访问修饰符。因此,一些构造方法可能适用于应用程序中的所有类,而其他构造方法仅适用于相同包,子类中的类,甚至仅适用于类本身(私有构造方法)。
下一篇: Java中的包