1.22 构造方法
構造方法是類的一種特殊方法,用來初始化類的一個新的對象,在創建對象(new 運算符)之后自動調用。Java 中的每個類都有一個默認的構造方法,并且可以有一個以上的構造方法。
Java 構造方法有以下特點:
- 方法名必須與類名相同,包括大小寫。
- 可以有 0 個、1 個或多個參數
- 構造方法不能在方法名前面定義方法類型,即不能定義void,也不能有返回值(不能有return語句)。
- 默認返回類型就是對象類型本身
- 構造方法不能自己調用,構造方法調用必須通過new語法,對象初始化的時候由系統自動調用。
- 一個類中的構造方法可以重載;在沒有定義構造方法的時候,編譯時自動生成一個默認構造方法(無參,方法體為空)。
- 構造方法的作用是完成對象的初始化,能夠把定義對象時的參數傳給對象的域。
值得注意的是,如果為構造方法定義了返回值類型或使用 void 聲明構造方法沒有返回值,編譯時不會出錯,但 Java 會把這個所謂的構造方法當成普通方法來處理。
這時候大家可能會產生疑問,構造方法不是沒有返回值嗎?為什么不能用 void 聲明呢?
簡單的說,這是 Java 的語法規定。實際上,類的構造方法是有返回值的,當使用 new 關鍵字來調用構造方法時,構造方法返回該類的實例,可以把這個類的實例當成構造器的返回值,因此構造器的返回值類型總是當前類,無須定義返回值類型。但必須注意不要在構造方法里使用 return 來返回當前類的對象,因為構造方法的返回值是隱式的。
注意:構造方法不能被 static、final、synchronized、abstract 和 native(類似于 abstract)修飾。構造方法用于初始化一個新對象,所以用 static 修飾沒有意義。
構造方法不能被子類繼承,所以用 final 和 abstract 修飾沒有意義。多個線程不會同時創建內存地址相同的同一個對象,所以用 synchronized 修飾沒有必要。
構造方法的語法格式如下:
class class_name {public class_name(){} // 默認無參構造方法public ciass_name([paramList]){} // 定義構造方法…// 類主體 }在一個類中,與類名相同的方法就是構造方法。每個類可以具有多個構造方法,但要求它們各自包含不同的方法參數。
無參構造方法
/*** 定義人類* @author user**/ public class People {// 定義屬性 private String name; // 實例化對象時,默認值是nullprivate int age; // 實例化對象時,默認值是0/*** 默認構造方法*/People(){System.out.println("默認構造方法!");}public void say(){System.out.println("我叫:"+name+",我今年:"+age);}public static void main(String[] args) {People people=new People();people.say();} }運行輸出:
默認構造方法! 我叫:null,我今年:0
實例化對象的時候,String類型的默認值是null,int基本類型的默認值是0 ;
People(){} 構造方法特點:
1,沒有返回值類型,區別于其他一般方法;
2,方法名和類名一樣;
有參數的構造方法,用來初始化對象屬性;
/*** 定義人類* @author user**/ public class People {// 定義屬性 private String name; // 實例化對象時,默認值是nullprivate int age; // 實例化對象時,默認值是0/*** 默認構造方法*/People(){System.out.println("默認構造方法!");}/*** 有參數的構造方法* @param name2* @param age2*/People(String name2,int age2){System.out.println("調用的是有參數的構造方法");name=name2;age=age2;}public void say(){System.out.println("我叫:"+name+",我今年:"+age);}public static void main(String[] args) {// People people=new People();People people=new People("張三",20);people.say();} }運行輸出:
1 2 調用的是有參數的構造方法 我叫:張三,我今年:20
這里我們定義了一個有參數的構造方法,參數有name2 age2,當調用構造方法的時候,用于賦值給name和age屬性;
注意:類的構造方法不是要求必須定義的。如果在類中沒有定義任何一個構造方法,則 Java 會自動為該類生成一個默認的構造方法。默認的構造方法不包含任何參數,并且方法體為空。如果類中顯式地定義了一個或多個構造方法,則 Java 不再提供默認構造方法。
提示:無參數的構造方法也被稱為 Nullary 構造方法。只有編譯程序自動加入的構造方法,才稱為默認構造函數。如果自行編寫無參數、沒有內容的構造函數,就不稱為默認構造函數了(只是 Nullary 構造函數)。雖然只是名詞定義,不過認證考試時要區別一下兩者的不同。
假如沒有構造方法,系統會自動生成一個默認的無參構造方法;
去掉剛才定義的People(){}
/*** 定義人類* @author user**/ public class People {// 定義屬性 private String name; // 實例化對象時,默認值是nullprivate int age; // 實例化對象時,默認值是0/*** 默認構造方法*//*People(){System.out.println("默認構造方法!");}*//*** 有參數的構造方法* @param name2* @param age2*//*People(String name2,int age2){System.out.println("調用的是有參數的構造方法");name=name2;age=age2;}*/public void say(){System.out.println("我叫:"+name+",我今年:"+age);}public static void main(String[] args) {People people=new People();//People people=new People("張三",20);people.say();} }我們把兩個構造方法備注了,運行的話,依然沒問題。
假如有構造方法,系統不會自動生成構造方法;
假如我們單獨去掉無參數的構造方法:
/*** 定義人類* @author user**/ public class People {// 定義屬性 private String name; // 實例化對象時,默認值是nullprivate int age; // 實例化對象時,默認值是0/*** 有參數的構造方法* @param name2* @param age2*/People(String name2,int age2){System.out.println("調用的是有參數的構造方法");name=name2;age=age2;}public void say(){System.out.println("我叫:"+name+",我今年:"+age);}public static void main(String[] args) {People people=new People();//People people=new People("張三",20);people.say();} } **例 2** 要在不同的條件下使用不同的初始化行為創建類的對象,這時候就需要在一個類中創建多個構造方法。下面通過一個示例來演示構造方法的使用。1)首先在員工類 Worker 中定義兩個構造方法,代碼如下:```java public class Worker {public String name; // 姓名private int age; // 年齡// 定義帶有一個參數的構造方法public Worker(String name) {this.name = name;}// 定義帶有兩個參數的構造方法public Worker(String name,int age) {this.name = name;this.age = age;}public String toString() {return "大家好!我是新來的員工,我叫"+name+",今年"+age+"歲。";} }在 Worker 類中定義了兩個屬性,其中 name 屬性不可改變。分別定義了帶有一個參數和帶有兩個參數的構造方法,并對其屬性進行初始化。最后定義了該類的 toString() 方法,返回一條新進員工的介紹語句。
提示:Object 類具有一個 toString() 方法,該方法是個特殊的方法,創建的每個類都會繼承該方法,它返回一個 String 類型的字符串。如果一個類中定義了該方法,則在調用該類對象時,將會自動調用該類對象的 toString() 方法返回一個字符串,然后使用“System.out.println(對象名)”就可以將返回的字符串內容打印出來。
2)在 TestWorker 類中創建 main() 方法作為程序的入口處,在 main() 方法中調用不同的構造方法實例化 Worker 對象,并對該對象中的屬性進行初始化,代碼如下:
public class TestWorker {public static void main(String[] args) {System.out.println("-----------帶有一個參數的構造方法-----------");// 調用帶有一個參數的構造方法Worker worker1 = new Worker("張強");System.out.println(worker1);System.out.println("-----------帶有兩個參數的構造方法------------");// 調用帶有兩個參數的構造方法Worker worker2 = new Worker("李麗",25);System.out.println(worker2);} }在上述代碼中,創建了兩個不同的 Worker 對象:一個是姓名為張強的員工對象,一個是姓名為李麗、年齡為 25 的員工對象。對于第一個 Worker 對象 Worker1,并未指定 age 屬性值,因此程序會將其值采用默認值 0。對于第二個 Worker 對象 Worker2,分別對其指定了 name 屬性值和 age 屬性值,因此程序會將傳遞的參數值重新賦值給 Worker 類中的屬性值。
注意:所有的 Java 對象都是在堆中構造的,構造器總是伴隨著 new 操作符一起使用。
運行 TestWorker 類,輸出的結果如下:
-----------帶有一個參數的構造方法----------- 大家好!我是新來的員工,我叫張強,今年0歲。 -----------帶有兩個參數的構造方法------------ 大家好!我是新來的員工,我叫李麗,今年25歲。通過調用帶參數的構造方法,在創建對象時,一并完成了對象成員的初始化工作,簡化了對象初始化的代碼。
總結
- 上一篇: 1.21 方法的可变参数(String.
- 下一篇: 1.23 实例:查询个人信息