創建實例的時候,我們經常需要同時初始化這個實例的字段,例如:
Person ming = new Person();
ming.setName("小明");
ming.setAge(12);
初始化對象實例需要3行代碼,而且,如果忘了調用setName()
或者setAge()
,這個實例內部的狀態就是不正確的。
這時,我們就需要構造方法。
class Person {
private String name;
private int age;
// 構造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
由於構造方法是如此特殊,所以構造方法的名稱就是類名。
構造方法的參數沒有限制,在方法內部,也可以編寫任意語句。
但是,和普通方法相比,構造方法沒有返回值(也沒有
void
),調用構造方法,必須用new
操作符 。
默認構造方法
是不是任何class
都有構造方法?是的。
那前面我們並沒有爲Person
類編寫構造方法,爲什麼可以調用new Person()
?
原因是如果一個類沒有定義構造方法,編譯器會自動爲我們生成一個默認構造方法,它沒有參數,也沒有執行語句,類似這樣:
class Person {
public Person() {
}
}
要特別注意的是,如果我們自定義了一個構造方法,那麼,編譯器就不再自動創建默認構造方法
如果既要能使用帶參數的構造方法,又想保留不帶參數的構造方法,那麼只能把兩個構造方法都定義出來:
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Xiao Ming", 15); // 既可以調用帶參數的構造方法
Person p2 = new Person(); // 也可以調用無參數構造方法
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
多構造方法
可以定義多個構造方法,在通過new
操作符調用的時候,編譯器通過構造方法的參數數量、位置和類型自動區分:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
this.age = 12;
}
public Person() {
}
}
如果調用 new Person("Xiao Ming", 20);
,會自動匹配到構造方法 public Person(String, int)
。
如果調用 new Person("Xiao Ming");
,會自動匹配到構造方法 public Person(String)
。
如果調用 new Person();
,會自動匹配到構造方法 public Person()
。
一個構造方法可以調用其他構造方法,這樣做的目的是便於代碼複用。調用其他構造方法的語法是this(…)
:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this(name, 18); // 調用另一個構造方法Person(String, int)
}
public Person() {
this("Unnamed"); // 調用另一個構造方法Person(String)
}
}