更新時(shí)間:2022-03-18 來源:黑馬程序員 瀏覽量:
在一個(gè)類中定義的方法如果同時(shí)滿足以下三個(gè)條件,該方法稱為構(gòu)造方法,具體如下:
1、方法名與類名相同
2、在方法名的前面沒有返回值類型的聲明
3、在方法中不能使用return語句返回一個(gè)值接下來通過一個(gè)案例來演示如何在類中定義構(gòu)造方法,如例程3-7所示。
例程3-7Example05.java
class Person { // 下面是類的構(gòu)造方法 public Person() { System.out.println("無參的構(gòu)造方法被調(diào)用了..."); } } public class Example05 { public static void main(String[] args) { Person p = new Person(); // 實(shí)例化Person 對象 } }
運(yùn)行結(jié)果如圖3-9所示。
在例程3-7的Person類中定義了一個(gè)無參的構(gòu)造方法Person()。從運(yùn)行結(jié)果可以看出,Person類中無參的構(gòu)造方法被調(diào)用了。這是因?yàn)榈?行代碼在實(shí)例化Person對象時(shí)會自動調(diào)用類的構(gòu)造方法,“new Person()”語句的作用除了會實(shí)例化Person對象,還會調(diào)用構(gòu)造方法Person()。
在一個(gè)類中除了定義無參的構(gòu)造方法,還可以定義有參的構(gòu)造方法,通過有參的構(gòu)造方法就可以實(shí)現(xiàn)對屬性的賦值。接下來對例程3-7進(jìn)行改寫,改寫后的代碼如例程3-8所示。
例程3-8Example06.java
class Person { int age; // 定義有參的構(gòu)造方法 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); // 實(shí)例化Person 對象 p.speak(); } }
3-8的Person類中定義了有參的構(gòu)造方法Person(int a)。第13行代碼中的“new
Person(20)”會在實(shí)例化對象的同時(shí)調(diào)用有參的構(gòu)造方法,并傳入了參數(shù)20。在構(gòu)造方法Person(int
a)中將20賦值給對象的age屬性。通過運(yùn)行結(jié)果可以看出,Person對象在調(diào)用speak()方法時(shí),其age屬性已經(jīng)被賦值為20。
構(gòu)造方法的重載
與普通方法一樣,構(gòu)造方法也可以重載,在一個(gè)類中可以定義多個(gè)構(gòu)造方法,只要每個(gè)構(gòu)造方法的參數(shù)類型或參數(shù)個(gè)數(shù)不同即可。在創(chuàng)建對象時(shí),可以通過調(diào)用不同的構(gòu)造方法來為不同的屬性進(jìn)行賦值。接下來通過一個(gè)案例來學(xué)習(xí)構(gòu)造方法的重載,如例程3-9所示。
例程3-9Example07.java
/ 為name屬性賦值 age = con_age; // 為age屬性賦值 } // 定義一個(gè)參數(shù)的構(gòu)造方法 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) { // 分別創(chuàng)建兩個(gè)對象p1 和p2 Person p1 = new Person("陳杰"); Person p2 = new Person("李芳", 18); // 通過對象p1 和p2 調(diào)用speak()方法 p1.speak(); p2.speak(); }
運(yùn)行結(jié)果如圖3-11所示。
例程3-9的Person類中定義了兩個(gè)構(gòu)造方法,它們構(gòu)成了重載。在創(chuàng)建p1對象和p2對象時(shí),根據(jù)傳入?yún)?shù)的不同,分別調(diào)用不同的構(gòu)造方法。從程序的運(yùn)行結(jié)果可以看出,兩個(gè)構(gòu)造方法對屬性賦值的情況是不一樣的,其中一個(gè)參數(shù)的構(gòu)造方法只針對name屬性進(jìn)行賦值,這時(shí)age屬性的值為默認(rèn)值0。
注意:
1、在Java中的每個(gè)類都至少有一個(gè)構(gòu)造方法,如果在一個(gè)類中沒有定義構(gòu)造方法,系統(tǒng)會自動為這個(gè)類創(chuàng)建一個(gè)默認(rèn)的構(gòu)造方法,這個(gè)默認(rèn)的構(gòu)造方法沒有參數(shù),在其方法體中沒有任何代碼,即什么也不做。
下面程序中Person類的兩種寫法效果是完全一樣的。
第一種寫法:
class Person { }
第二種寫法:
class Person { public Person() { } }
對于第一種寫法,類中雖然沒有聲明構(gòu)造方法,但仍然可以用new
Person()語句來創(chuàng)建Person類的實(shí)例對象。由于系統(tǒng)提供的構(gòu)造方法往往不能滿足需求,因此,我們可以自己在類中定義構(gòu)造方法,一旦為該類定義了構(gòu)造方法,系統(tǒng)就不再提供默認(rèn)的構(gòu)造方法了,具體代碼如下所示。
class Person { int age; public Person(int x) { age = x; } }
上面的Person類中定義了一個(gè)對成員變量賦初值的構(gòu)造方法,該構(gòu)造方法有一個(gè)參數(shù),這時(shí)系統(tǒng)就不再提供默認(rèn)的構(gòu)造方法,接下來再編寫一個(gè)測試程序調(diào)用上面的Person類,如例程3-10所示。
例程3-10Example08.java
public class Example08 { public static void main(String[] args) { Person p = new Person(); // 實(shí)例化Person 對象 } }
編譯程序報(bào)錯(cuò),結(jié)果如圖3-12所示。
從圖中可以看出程序在編譯時(shí)報(bào)錯(cuò),其原因是調(diào)用new Person()創(chuàng)建Person類的實(shí)例對象時(shí),需要調(diào)用無參的構(gòu)造方法,而我們并沒有定義無參的構(gòu)造方法,只是定義了一個(gè)有參的構(gòu)造方法,系統(tǒng)將不再自動生成無參的構(gòu)造方法。為了避免出現(xiàn)上面的錯(cuò)誤,在一個(gè)類中如果定義了有參的構(gòu)造方法,最好再定義一個(gè)無參的構(gòu)造方法。
2、思考一下,聲明構(gòu)造方法時(shí),可以使用private訪問修飾符嗎?下面就來運(yùn)行一下例程3-11,看看會出現(xiàn)什么結(jié)果。
例程3-11Example09.java
class Person { // 定義構(gòu)造方法 private Person() { System.out.println("調(diào)用無參的構(gòu)造方法"); } } public class Example09 { public static void main(String[] args) { Person p = new Person(); } }
圖3-13運(yùn)行結(jié)果
從圖3-13中可以看出,程序在編譯時(shí)出現(xiàn)了錯(cuò)誤,錯(cuò)誤提示為private關(guān)鍵字修飾的構(gòu)造方法Person()只能在Person類中被訪問。也就是說Person()構(gòu)造方法是私有的,不可以被外界調(diào)用,也就無法在類的外部創(chuàng)建該類的實(shí)例對象。因此,為了方便實(shí)例化對象,構(gòu)造方法通常會使用public來修飾。