構(gòu)造器(Constructor)
創(chuàng)建一個(gè)對(duì)象時(shí),我們會(huì)寫如下的代碼:
User user = new User();
有同學(xué)可能會(huì)認(rèn)為new右邊寫是類型User的類名,但是實(shí)際上這里調(diào)用的是一個(gè)方法。
該方法用來創(chuàng)建一個(gè)類型的實(shí)例玫恳,因?yàn)樗且粋€(gè)很特殊的方法,我們稱之為構(gòu)造方法/構(gòu)造器/構(gòu)造函數(shù)(Constructor)。
構(gòu)造器的作用
構(gòu)造器的作用:可用于創(chuàng)建實(shí)例象和完成實(shí)例初始化時(shí)內(nèi)存分配鳞绕。
注意:如果在構(gòu)造器中沒有顯示地給域賦初值,那么就會(huì)被自動(dòng)賦予默認(rèn)值,這和動(dòng)態(tài)創(chuàng)建數(shù)值是元素的默認(rèn)值是一樣的:數(shù)值為0,布爾值為flase,對(duì)象引用為null.
構(gòu)造器的特點(diǎn):
1.構(gòu)造方法名稱與類名相同:這樣我們才知道當(dāng)前創(chuàng)建的是哪個(gè)類型的實(shí)例。
2.不用定義返回值類型
3.不需要寫return語句
4.和類的修飾符相同:如果類前使用了public修飾,則構(gòu)造器也要使用public修飾
//構(gòu)造器
public class ConstructorDemo {
//調(diào)用構(gòu)造器創(chuàng)建User類的實(shí)例對(duì)象
User user = new User();
}
class User{
private String name;
private int age;
}
疑問:上述代碼,并沒有在User類中看到構(gòu)造器的定義尸曼,調(diào)用構(gòu)造器也能成功new一個(gè)User對(duì)象,這是為什么呢?
默認(rèn)構(gòu)造器
當(dāng)一個(gè)類中沒有顯示定義構(gòu)造器時(shí),那么編譯器會(huì)默認(rèn)給該類提供一個(gè)構(gòu)造器们何,其特點(diǎn)是:無參、無方法體控轿、訪問修飾符和所在類的訪問修飾符相同冤竹。
注意:僅當(dāng)類沒有提供任何構(gòu)造器時(shí),系統(tǒng)才會(huì)提供一個(gè)默認(rèn)的構(gòu)造器,此時(shí),該默認(rèn)構(gòu)造器是可以通過查看編譯之后的代碼看到的,(可以使用XJad查看).
構(gòu)造器重載
我們說,方法可以重載, 這解決了同一種功能的方法因?yàn)閰?shù)列表不同,而帶來方法名稱不同的問題.而構(gòu)造器是一種特殊的方法,那么構(gòu)造器自然也是可以重載的.
值得注意的是,如果在編寫類的時(shí)候給出了構(gòu)造器,那么系統(tǒng)就不會(huì)在提供默認(rèn)構(gòu)造器
//構(gòu)造器
public class ConstructorDemo {
public static void main(String[] args) {
//調(diào)用構(gòu)造器創(chuàng)建User類的實(shí)例對(duì)象
//User user = new User();//報(bào)錯(cuò) :The constructor User() is undefined
//注意:如果在編寫類的時(shí)候給出了構(gòu)造器,那么系統(tǒng)就不會(huì)在提供默認(rèn)構(gòu)造器,如果還想使用無參構(gòu)造器,可以自己添加一個(gè)
User user1 = new User("ShenJN");//調(diào)用了一個(gè)參數(shù)的構(gòu)造器
User user2 = new User("ShenJN", 11);//調(diào)用了兩個(gè)參數(shù)的構(gòu)造器
}
}
class User {
private String name;
private int age;
User(String n) {
name = n;
System.out.println("調(diào)用了一個(gè)參數(shù)的構(gòu)造器");
}
User(String n, int a) {
name = n;
age = a;
System.out.println("調(diào)用了兩個(gè)參數(shù)的構(gòu)造器");
}
}
上述代碼,有一個(gè)地方令我很不爽,在構(gòu)造器的變量名很不直觀,我想這樣寫代碼
class User {
private String name;
private int age;
User(String name, int age) {
name = name;
age = age;
System.out.println("調(diào)用了兩個(gè)參數(shù)的構(gòu)造器");
}
}
但是,這樣寫肯定是有問題的則,構(gòu)造器中name和age的值根本沒有傳給User類的字段,而是自己賦值給了自己,那要怎么解決呢?解決方案,可以使用this關(guān)鍵字.
什么是this
this:表示當(dāng)前對(duì)象,哪個(gè)對(duì)象調(diào)用this所在的成員茬射,那么this就表示哪個(gè)對(duì)象.
一般的this出現(xiàn)在兩個(gè)地方:
1.構(gòu)造器中:表示當(dāng)前構(gòu)造器創(chuàng)建的對(duì)象鹦蠕。
2.方法中:表示當(dāng)前調(diào)用this所在方法的對(duì)象。
this的作用:
1.解決成員變量和參數(shù)之間的二義性,必須使用;
2.同類中實(shí)例方法間互調(diào)
3.將當(dāng)前對(duì)象作為參數(shù)傳遞給另一個(gè)方法
3.講當(dāng)前對(duì)象作為方法的返回值
4.構(gòu)造器重載的互調(diào)在抛,this([參數(shù)])必須寫在構(gòu)造方法第一行
注意:static不能和this一起使用
class User {
private String name;
private int age;
//解決剛剛的上述問題
User(String name) {
this.name = name;
System.out.println("調(diào)用了一個(gè)參數(shù)的構(gòu)造器");
}
//解決剛剛的上述問題
User(String name, int age) {
this.name = name;
this.age = age;
System.out.println("調(diào)用了兩個(gè)參數(shù)的構(gòu)造器");
}
}
上述代碼沒有問題,但是存在了代碼重復(fù)的問題this.age = age;
注意:當(dāng)有多個(gè)構(gòu)造器或者重載方法時(shí),我們一般使用少參數(shù)的方法調(diào)用多參數(shù)的方法,參數(shù)越多,該方法考慮的因素也就越多,功能也更強(qiáng)大.
但是,在構(gòu)造器中調(diào)用重載構(gòu)造器,只能放在構(gòu)造方法第一行
class User {
private String name;
private int age;
//解決上述問題
User(String name) {
//在構(gòu)造器中調(diào)用重載構(gòu)造器,只能放在構(gòu)造方法第一行;
this(name,0);
System.out.println("調(diào)用了一個(gè)參數(shù)的構(gòu)造器");
}
User(String name, int age) {
this.name = name;
this.age = age;
System.out.println("調(diào)用了兩個(gè)參數(shù)的構(gòu)造器");
}
}