類與對(duì)象是整個(gè)面向?qū)ο笤O(shè)計(jì)的核心所在,也是所有概念的基礎(chǔ)。類本身屬于引用數(shù)據(jù)類型,所以類的使用上會(huì)牽扯到內(nèi)存分配問(wèn)題。
目錄

1.認(rèn)識(shí)類與對(duì)象
現(xiàn)在大家可以聽(tīng)懂本人說(shuō)話,我們具備共同特征:我們都是中國(guó)人,母語(yǔ)都是漢語(yǔ)。那么具備這些特征的人很多,那么就自然是一個(gè)群體,而群體的特征就是整個(gè)類的定義概念。所謂的類描述的就是共性特征。
任何時(shí)候只是依靠共性的特征是無(wú)法進(jìn)行精準(zhǔn)描述的,那么就需要一些個(gè)性化的特點(diǎn)。就可以描述一個(gè)個(gè)獨(dú)立的事物。所以這樣就可以推斷出:所謂類指的就是一個(gè)共性的概念,而我們的對(duì)象指的是一個(gè)具體的可以使用的事物。
那么很明顯在實(shí)際的開(kāi)發(fā)過(guò)程中,一定需要首先產(chǎn)生類才可以產(chǎn)生對(duì)象。那么對(duì)象的所有操作的行為都一定在類中進(jìn)行了完整定義。類中沒(méi)有定義的功能,那么對(duì)象一定是無(wú)法使用。
類中的組成:方法(操作的行為),屬性(變量,描述每一個(gè)對(duì)象的具體特點(diǎn))
1.1類的概念
類是一個(gè)模板,一個(gè)藍(lán)本,或者說(shuō)是合約,用來(lái)描述對(duì)象的行為和狀態(tài)。
1.2對(duì)象的概念
對(duì)象是類的一個(gè)實(shí)例,有狀態(tài)與行為。
一個(gè)對(duì)象的狀態(tài)(或特征,屬性)是由具有當(dāng)前值的數(shù)據(jù)域來(lái)表示。
一個(gè)對(duì)象的行為(動(dòng)作)是由方法來(lái)定義的。調(diào)用對(duì)象的一個(gè)方法就是要求對(duì)象完成一個(gè)動(dòng)作。
2.類與對(duì)象的定義與使用
2.1類的定義
類必須先定義才能使用。類是創(chuàng)建對(duì)象的模板,創(chuàng)建對(duì)象也叫 類的實(shí)例化 。
如果程序之中要進(jìn)行 類的定義 可以使用 class 關(guān)鍵字完成,而我們定義的語(yǔ)法如下:
//所有的程序都以{}為分界符
class 類名稱{
? ? ? ? 屬性;
? ? ? ? 屬性;
? ? ? ? 方法(){}
}
此時(shí)的方法不再由主類直接調(diào)用,而是要通過(guò)對(duì)象進(jìn)行調(diào)用。
范例:定義類
定義一個(gè)類,類名稱每個(gè)單詞首字母要求大寫(xiě) Person 類
class Person{
String name;
int age;
public void info(){
System.out.println(“name=”+name+",age="+age);
}
}
在這個(gè)類中只定義了兩個(gè)屬性和一個(gè)方法,特別需要注意的是,類中可以定義的屬性數(shù)量以及方法數(shù)量是沒(méi)有限制的,而且在編寫(xiě)的時(shí)候,每一個(gè)方法的代碼盡量不要特別長(zhǎng)。
2.2對(duì)象的定義(創(chuàng)建對(duì)象)
對(duì)象是類的一個(gè)實(shí)例,創(chuàng)建對(duì)象的過(guò)程也叫類的實(shí)例化。對(duì)象是以類為模板來(lái)創(chuàng)建的。
類定義完成之后是不能直接去使用的,如果要想使用類那么必須產(chǎn)生對(duì)象,
而 對(duì)象的定義 分為以下兩種語(yǔ)法形式:
- 聲明并實(shí)例化對(duì)象:
類名稱 對(duì)象名稱 = new 類名稱();
- 分布進(jìn)行對(duì)象實(shí)例化:
2.1聲明對(duì)象:
類名稱 對(duì)象名稱 = null;
2.2 實(shí)例化對(duì)象:
對(duì)象名稱 = new 類名稱();
2.3對(duì)象的使用(訪問(wèn)類的成員變量和方法)
引用數(shù)據(jù)類型的最大特征在于 內(nèi)存的分配操作 ,而只要出現(xiàn)有關(guān)鍵字new 那么就只有一個(gè)解釋: 開(kāi)辟新內(nèi)存(內(nèi)存是不可能無(wú)限開(kāi)辟,所以這時(shí)候所謂的性能調(diào)優(yōu)調(diào)整的就是內(nèi)存問(wèn)題)
????????所有的對(duì)象只有實(shí)例化之后才可以真正使用,而對(duì)象的使用都是圍繞的類進(jìn)行的,那么此時(shí)就有兩種形式:
- 調(diào)用類中的屬性:
對(duì)象.屬性 = 內(nèi)容;- 調(diào)用類中的方法:
對(duì)象.方法();
范例: 聲明并實(shí)例化對(duì)象
public class Test{
public static void main(String[] args){
Person person = new Person(); 這段表示實(shí)例化對(duì)象
person.name = "張三"; 設(shè)置對(duì)象中的屬性
person.age = 18;
person.info(); 調(diào)用對(duì)象中的方法
}
}
3.對(duì)象的內(nèi)存分析
如果要進(jìn)行對(duì)象的產(chǎn)生分析,那么首先必須要清楚 引用類型。引用類型指的是內(nèi)存空間的操作。而對(duì)于現(xiàn)在的內(nèi)存主要會(huì)使用兩塊內(nèi)存空間:
- 堆內(nèi)存空間:保存真正的數(shù)據(jù),堆內(nèi)存保存的是對(duì)象的屬性信息;
- 棧內(nèi)存空間:保存的堆內(nèi)存的i地址,堆內(nèi)存操作權(quán),如果要想簡(jiǎn)化理解,可以理解為保存的是對(duì)象名稱;
所以按照之前的程序,那么現(xiàn)在就可以給出如下的內(nèi)存參考圖:
class Person{
String name;
int age;
public void info(){
System.out.println("name="+name+",age="+age);
}
}
public class Test{
public static void main(String[] args){
Person per = new Person();
per.name = "張三";
per.age = 18;
per.info();
}
}

但是對(duì)于對(duì)象的產(chǎn)生實(shí)際要知道一共會(huì)有兩種格式,現(xiàn)在使用的是 聲明并實(shí)例化對(duì)象的格式,那么也可以 分布的方式完成。
public class Test{
public static void main(String[] args){
Person per = null; 聲明一個(gè)對(duì)象
per = new Person(); 實(shí)例化對(duì)象
per.name = "張三"; 設(shè)置對(duì)象中的屬性
per.age = 18;
per.info(); 調(diào)用類中的方法
}
}
內(nèi)存圖:
04.png
但是千萬(wàn)要記住一點(diǎn),對(duì)象(所有的引用數(shù)據(jù)類型)必須在其開(kāi)辟空間之后才可以使用,如果使用了未開(kāi)辟的內(nèi)存空間的引用數(shù)據(jù)類型,則將出現(xiàn)" NullPointerException:"
這個(gè)時(shí)候只聲明了對(duì)象而并沒(méi)有為其開(kāi)辟堆內(nèi)存空間,而本程序在編譯的時(shí)候不會(huì)產(chǎn)生任何的語(yǔ)法錯(cuò)誤,但是在執(zhí)行的時(shí)候會(huì)出現(xiàn)如下的錯(cuò)誤提示:
Exception in thread "main" java.lang.NullPointerException
????? at Test.main(Test.java:11)
“NullPointerException:” 只有引用數(shù)據(jù)類型才會(huì)產(chǎn)生此類異常,以后出現(xiàn)了就根據(jù)錯(cuò)誤的位置觀察對(duì)象是否實(shí)例化。
4.引用傳遞初次分析
所有初學(xué)者最難的部分就是引用傳遞分析,以后的開(kāi)發(fā)中都是引用傳遞。
引用的本質(zhì) 就在于別名,而這個(gè)別名只不過(guò)是放在了棧內(nèi)存之中,即:一塊堆內(nèi)存可以被多個(gè)棧內(nèi)存所指向。
范例:觀察引用傳遞。
代碼 1:
public class Test{
public static void main(String[] args){
Person per1 = new Person();
per1.name = "小于子";
per1.age = 30;
}
}
代碼 改:
public class Test{
public static void main(String[] args){
Person per1 = new Person();
per1.name = "小于子";
per1.age = 30;
此步驟就是引用傳遞操作
Person per2 = per1;
per2.name="狗剩";
per2.info();
}
}
此時(shí)需要通過(guò)內(nèi)存關(guān)系圖來(lái)進(jìn)行程序的執(zhí)行觀察。

范例2: 觀察引用傳遞。
public class Test{
public static void main(String[] args){
Person per1 = new Person();
Person per2 = new Person();
per1.name = "小于子";
per1.age = 30;
per2.name = "張三";
per2.age = 20;
//此步驟就是引用傳遞操作
per2 = per1;
per2.name="狗剩";
per2.info();
}
}
觀察此時(shí)的內(nèi)存分析圖:

在程序開(kāi)發(fā)過(guò)程之中,所謂的 垃圾空間 指的就是沒(méi)有任何棧內(nèi)存指向的堆內(nèi)存空間,所有的垃圾空間將會(huì)不定期被 垃圾收集器 (GC ,Garbage Collector),進(jìn)行回收以實(shí)現(xiàn)內(nèi)存空間的釋放,不過(guò)從實(shí)際開(kāi)發(fā)來(lái)講,雖然Java提供有g(shù)c,但是gc也會(huì)造成程序性能的下降,
所以開(kāi)發(fā)過(guò)程中一定要控制好你對(duì)象的產(chǎn)生數(shù)量,即無(wú)用的對(duì)象盡可能少產(chǎn)生。
