在 Java 中過載建構函式
本教程介紹如何在 Java 中過載建構函式。我們還列出了一些示例程式碼,你可以遵循這些示例程式碼以更好地理解該主題。
建構函式是一種為類物件分配記憶體併為該物件初始化類屬性的方法。如果沒有為類建立建構函式,則 Java 提供一個預設建構函式。
例如,在下面的類中沒有定義建構函式。不過,我們可以建立該類的物件,同時將屬性初始化為其預設值(在本例中為 null)。
Java 中的預設建構函式
class Student {
String name;
Double gpa;
}
public class Main {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.name + "\t" + s.gpa);
}
}
輸出:
null null
建構函式過載的概念類似於方法過載,這意味著我們對單個類有多個建構函式。建構函式過載是為了以不同的方式初始化類的成員變數。
我們可以根據需要建立任意數量的過載建構函式。唯一的條件是過載的建構函式應該在它們採用的引數數量和型別上有所不同。
例如,參考下面顯示的具有兩個屬性的 Student
類:student name
和 GPA
。為該類定義了一個建構函式,它接受一個字串名稱和一個雙 GPA
作為引數,併為新物件初始化相應的屬性。
Java 中的引數化建構函式
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
gpa = g;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Justin", 9.75);
System.out.println(s.name + "\t" + s.gpa);
}
}
輸出:
Justin 9.75
沒有建構函式過載的程式碼
考慮在建立新物件時僅將學生姓名傳遞給建構函式的場景;在這種情況下,GPA
應自動設定為 null
。如果我們不過載建構函式而只傳遞名稱,則會出現以下編譯錯誤。
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
gpa = g;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Justin");
System.out.println(s.name + "\t" + s.gpa);
}
}
輸出:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The constructor Student(String) is undefined
at ConstructorOverloading.main(ConstructorOverloading.java:18)
Java 中的建構函式過載
我們可以建立一個僅以學生姓名作為引數的過載建構函式來解決上述情況。呼叫此建構函式時,我們會將 GPA
設定為 null
。
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
this.gpa = g;
}
Student(String s) {
name = s;
gpa = null; // Setting GPA to null
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student("Justin");
Student s2 = new Student("Jessica", 9.23);
System.out.println(s1.name + "\t" + s1.gpa);
System.out.println(s2.name + "\t" + s2.gpa);
}
}
輸出:
Justin null
Jessica 9.23
考慮另一種情況,其中建立了 Student
物件,但名稱和 GPA
均未提及。我們可以建立另一個不帶引數的過載建構函式(預設建構函式)並將 name
和 GPA
屬性設定為 null
。
請記住,Java 僅在沒有為類建立其他建構函式時才提供預設建構函式。但是對於我們的類,建構函式已經存在,因此我們需要建立一個預設建構函式。
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
gpa = g;
}
Student(String s) {
name = s;
gpa = null;
}
Student() {
name = null;
gpa = null;
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student("Justin");
Student s3 = new Student("Jessica", 9.23);
System.out.println(s1.name + "\t" + s1.gpa);
System.out.println(s2.name + "\t" + s2.gpa);
System.out.println(s3.name + "\t" + s3.gpa);
}
}
輸出:
null null
Justin null
Jessica 9.23
建構函式過載最佳實踐
過載建構函式時沒有固定的指導方針。但是,我們可以遵循一些推薦的最佳實踐,以避免混淆並減少錯誤的範圍。
- 應該使用
this
關鍵字來引用類的成員變數。它避免了混淆並使我們的程式碼更具可讀性。 - 我們還可以將更直觀的引數名稱傳遞給建構函式。例如,如果建構函式初始化 name 欄位,則建構函式簽名可以是
Student(String name)
而不是Student(String s)
。使用this
關鍵字,我們可以區分稱為name
的引數和也稱為name
的類屬性。
讓我們繼續 Student
類的示例,並在建構函式中使用 this
關鍵字。
class Student {
String name;
Double gpa;
Student(String name, Double gpa) // passing more intuitive parameter names
{
this.name = name; // using this keyword to avoid confusion
this.gpa = gpa;
}
Student(String name) {
this.name = name;
this.gpa = null;
Student()
this.name = null;
this.gpa = null;
}
}
- 一個類只有一個
單一主建構函式
也是一個很好的做法,所有剩餘的建構函式都應該呼叫這個主建構函式來初始化屬性。 - 我們可以使用
this()
函式從另一個建構函式呼叫建構函式。我們傳遞給this()
的屬性的數量和型別將決定呼叫哪個建構函式。 - 它會減少程式碼冗餘,我們只需要為單個建構函式編寫邏輯。
- 在
Student
類中,我們需要三個過載的建構函式。主要建構函式將是引數化的建構函式,它以name
和GPA
作為引數。另外兩個過載的建構函式將簡單地呼叫主建構函式並將引數的值作為null
傳遞。
class Student {
String name;
Double gpa;
Student(String name, Double gpa) // Primary Constructor that sets the attribute values
{
this.name = name;
this.gpa = gpa;
}
Student(String name) {
this(name, null); // Calling the primary constructor with GPA as null
}
Student() {
this(null, null); // Calling the primary constructor with both parameters as null
}
}
過載建構函式
過載建構函式是為了以不同的方式初始化類的屬性。過載的建構函式應該在引數數量或傳遞給它們的引數的資料型別方面有所不同。
每個建構函式的簽名應該與其他建構函式不同。我們應該使用 this
關鍵字來引用類屬性和其他建構函式,因為它使我們的程式碼更少冗餘且更易於理解。