1.1 構(gòu)造方法介紹
在開發(fā)中經(jīng)常需要在創(chuàng)建對象的同時明確對象的屬性值,比如員工入職公司就要明確他的姓名、年齡等屬性信息。
那么,創(chuàng)建對象就要明確屬性值,那怎么解決呢?也就是在創(chuàng)建對象的時候就要做的事情,當(dāng)使用new關(guān)鍵字創(chuàng)建對象時,怎么給對象的屬性初始化值呢?這就要學(xué)習(xí)Java另外一門小技術(shù),構(gòu)造方法。
那什么是構(gòu)造方法呢?從字面上理解即為構(gòu)建創(chuàng)造時用的方法,即就是對象創(chuàng)建時要執(zhí)行的方法。既然是對象創(chuàng)建時要執(zhí)行的方法,那么只要在new對象時,知道其執(zhí)行的構(gòu)造方法是什么,就可以在執(zhí)行這個方法的時候給對象進(jìn)行屬性賦值。
? 構(gòu)造方法的格式:
修飾符 構(gòu)造方法名(參數(shù)列表)
{
}
? 構(gòu)造方法的體現(xiàn):
? 構(gòu)造方法沒有返回值類型。也不需要寫返回值。因?yàn)樗菫闃?gòu)建對象的,對象創(chuàng)建完,方法就執(zhí)行結(jié)束。
? 構(gòu)造方法名稱必須和類型保持一致。
? 構(gòu)造方法沒有具體的返回值。
? 構(gòu)造方法的代碼體現(xiàn):
class Person {
// Person的成員屬性age和name
private int age;
private String name;
// Person的構(gòu)造方法,擁有參數(shù)列表
Person(int a, String nm) {
// 接受到創(chuàng)建對象時傳遞進(jìn)來的值,將值賦給成員屬性
age = a;
name = nm;
}
}
1.2 構(gòu)造方法調(diào)用和內(nèi)存圖解
理解構(gòu)造方法的格式和基本功能之后,現(xiàn)在就要研究構(gòu)造方法是怎么執(zhí)行的呢?在創(chuàng)建對象的時候是如何初始化的呢?
構(gòu)造方法是專門用來創(chuàng)建對象的,也就是在new對象時要調(diào)用構(gòu)造方法?,F(xiàn)在來看看如何調(diào)用構(gòu)造方法。
class Person {
// Person的成員屬性age和name
private int age;
private String name;
// Person的構(gòu)造方法,擁有參數(shù)列表
Person(int a, String nm) {
// 接受到創(chuàng)建對象時傳遞進(jìn)來的值,將值賦給成員屬性
age = a;
name = nm;
}
public void speak() {
System.out.println("name=" + name + ",age=" + age);
}
}
class PersonDemo {
public static void main(String[] args) {
// 創(chuàng)建Person對象,并明確對象的年齡和姓名
Person p2 = new Person(23, "張三");
p2.speak();
}
}
上述代碼演示了創(chuàng)建對象時構(gòu)造方法的調(diào)用。即在創(chuàng)建對象時,會調(diào)用與參數(shù)列表對應(yīng)的構(gòu)造方法。
上述代碼的圖解:
? 圖解說明:
1、首先會將main方法壓入棧中,執(zhí)行main方法中的 new Person(23,"張三");
2、在堆內(nèi)存中分配一片區(qū)域,用來存放創(chuàng)建的Person對象,這片內(nèi)存區(qū)域會有屬于自己的內(nèi)存地址(0x88)。然后給成員變量進(jìn)行默認(rèn)初始化(name=null,age=0)。
3、執(zhí)行構(gòu)造方法中的代碼(age = a ; name = nm;),將變量a對應(yīng)的23賦值給age,將變量nm對應(yīng)的”張三賦值給name,這段代碼執(zhí)行結(jié)束后,成員變量age和name的值已經(jīng)改變。執(zhí)行結(jié)束之后構(gòu)造方法彈棧,Person對象創(chuàng)建完成。將Person對象的內(nèi)存地址0x88賦值給p2。
1.3 默認(rèn)構(gòu)造方法和細(xì)節(jié)
在沒有學(xué)習(xí)構(gòu)造方法之前,我們也可以通過new關(guān)鍵字創(chuàng)建對象,并調(diào)用相應(yīng)的方法,同時在描述事物時也沒有寫構(gòu)造方法。這是為什么呢?
在之前學(xué)習(xí)的過程中,描述事物時,并沒有顯示指定構(gòu)造方法,當(dāng)在編譯Java文件時,編譯器會自動給class文件中添加默認(rèn)的構(gòu)造方法。如果在描述類時,我們顯示指定了構(gòu)造方法,那么,當(dāng)在編譯Java源文件時,編譯器就不會再給class文件中添加默認(rèn)構(gòu)造方法。
class Person {
//如果沒有顯示指定構(gòu)造方法,編譯會在編譯時自動添加默認(rèn)的構(gòu)造方法
//Person(){} //空參數(shù)的默認(rèn)構(gòu)造方法
}
當(dāng)在描述事物時,要不要在類中寫構(gòu)造方法呢?這時要根據(jù)描述事物的特點(diǎn)來確定,當(dāng)描述的事物在創(chuàng)建其對象時就要明確屬性的值,這時就需要在定義類的時候書寫帶參數(shù)的構(gòu)造方法。若創(chuàng)建對象時不需要明確具體的數(shù)據(jù),這時可以不用書寫構(gòu)造方法(不書寫也有默認(rèn)的構(gòu)造方法)。
? 構(gòu)造方法的細(xì)節(jié):
1、一個類中可以有多個構(gòu)造方法,多個構(gòu)造方法是以重載的形式存在的
2、構(gòu)造方法是可以被private修飾的,作用:其他程序無法創(chuàng)建該類的對象。
class Person {
private int age;
private String name;
// 私有無參數(shù)的構(gòu)造方法,即外界不能通過new Person();語句創(chuàng)建本類對象
private Person() {
}
// 多個構(gòu)造方法是以重載的形式存在
Person(int a) {
age = a;
}
Person(String nm, int a) {
name = nm;
age = a;
}
}
1.4 構(gòu)造方法和一般方法區(qū)別
到目前為止,學(xué)習(xí)兩種方法,分別為構(gòu)造方法和一般方法,那么他們之間有什么異同呢?
構(gòu)造方法在對象創(chuàng)建時就執(zhí)行了,而且只執(zhí)行一次。
一般方法是在對象創(chuàng)建后,需要使用時才被對象調(diào)用,并可以被多次調(diào)用。
? 問題:
有了構(gòu)造方法之后可以對對象的屬性進(jìn)行初始化,那么還需要對應(yīng)的set和get方法嗎?
需要相應(yīng)的set和get方法,因?yàn)閷ο笤趧?chuàng)建之后需要修改和訪問相應(yīng)的屬性值時,在這時只能通過set或者get方法來操作。
思考,如下代碼有問題嗎?
class Person {
void Person() {
}
}
class PersonDemo {
public static void main(String[] args) {
Person p = new Person();
}
}