- 之前在阿里云大學(xué)公開課上學(xué)了一些Java面向?qū)ο缶幊蹋瑳Q定把筆記和代碼更新下
- 本文從面向?qū)ο缶幊?/strong>開始記錄(ps.阿里云老師講的很有趣 = w =)怎爵,阿里云大學(xué)Java網(wǎng)課網(wǎng)址鏈接
第一章 類與對象
課時2:面向?qū)ο蠛喗?/h2>
面向過程 | 面向?qū)ο?/th> |
---|---|
面對一個問題的解決方案更多情況是面對一個問題的解決方案 | 模塊化設(shè)計喷众,可以重用配置 |
面向?qū)ο笥腥齻€主要特性:
- 封裝性:內(nèi)部操作對外部不可見剃允,當(dāng)內(nèi)部的操作都不可直接在外部使用時才是安全的桩了;
- 繼承性:在已有結(jié)構(gòu)的基礎(chǔ)上繼續(xù)進(jìn)行功能的擴(kuò)充众旗;比如手機(jī)是圍繞其通話功能進(jìn)行擴(kuò)充的踱侣。
- 多態(tài)性:在繼承性基礎(chǔ)上擴(kuò)充的概念粪小,指的是類型的轉(zhuǎn)化處理
面向?qū)ο箝_發(fā)的步驟:(由生活場景進(jìn)行程序分析最好)
- OOA:面向?qū)ο蠓治?/li>
- OOD:面向?qū)ο笤O(shè)計
- OOP:面向?qū)ο缶幊?/li>
課時3:類與對象簡介
- 區(qū)別每個事物的不同是根據(jù)其屬性,每一個屬性的集合構(gòu)建出一個群體抡句,這個抽象群體就是類探膊;
- 抽象群體的一個實(shí)際群體,就是類的實(shí)例化對象待榔。
類 | 對象 |
---|---|
某一類事物的抽象概念 | 具體的產(chǎn)物 |
一個模板 | 可以使用的模板實(shí)例 |
類中一般有兩個組成:
- 成員屬性:比如一個人(事物)的年齡姓名(屬性)
- 操作方法:定義對象處理的行為逞壁,比如人(事物)會唱、跳锐锣、rap(行為)
課時4:類與對象定義
Java中類是一個獨(dú)立的結(jié)構(gòu)體腌闯,所以需要用class來定義
public class Person {
String name;//姓名屬性
int age;//年齡屬性
void tell() {//tell行為
System.out.println("name" + name + "age" + age);
}
}
有了類,如果需要產(chǎn)生對象:
- 聲明并實(shí)例化對象:
類名稱 對象名稱 = new 類名稱(屬性參數(shù))
- 分步驟完成:
聲明對象:類名稱 對象名稱 = null雕憔;
實(shí)例化對象:對象名稱 = new 類名稱()姿骏;
有了對象需要調(diào)用對象:
- 調(diào)用屬性:
實(shí)例化對象.對象屬性;
- 調(diào)用方法行為:
實(shí)例化對象.方法名稱(需要傳給方法行為的參數(shù))斤彼;
例子如下:
public class C4Person {
public static void main(String args[])
{
Person per = new Person();//聲明實(shí)例化對象
per.name = "Tom";
per.age = 3;
per.tell();//方法的調(diào)用
}
}
如果并沒有進(jìn)行對象的屬性內(nèi)容設(shè)置分瘦,則屬性內(nèi)容為屬性的默認(rèn)值(String:null int:0)
課時5:對象內(nèi)存分析
Java中類屬于引用數(shù)據(jù)類型,困難之處在于要進(jìn)行內(nèi)存的管理琉苇。所以對內(nèi)存管理進(jìn)行一下分析嘲玫。
- 通過棧內(nèi)存找到堆內(nèi)存,子啊找到對象的具體信息
堆內(nèi)存 | 棧內(nèi)存 |
---|---|
保存的是對象的具體信息并扇,在程序中堆內(nèi)存的空間開辟由new完成 | 一塊堆內(nèi)存的地址 |
-
課時4的內(nèi)存分析(聲明并實(shí)例化對象):
- 分步驟完成對象
所有調(diào)用類的屬性和方法在實(shí)例化對象完成后才能執(zhí)行 - 錯誤代碼:
只是聲明了對象但是沒有實(shí)例化去团,(棧內(nèi)存沒有指向堆內(nèi)存的指針,以及堆內(nèi)存沒有開辟,只有引用數(shù)據(jù)類型有此報錯I薄c迦蕖!)**旺坠,調(diào)用后會報NullPointerException
乔遮,空指針異常
課時6:對象引用分析
既然類本身屬于引用數(shù)據(jù)類型,就牽扯到內(nèi)存的引用傳遞取刃,可以被不同的棧內(nèi)存指向蹋肮,也可以更換指向。
-
引用傳遞示例
- 通過方法的引用傳遞:
與之前的差別最大的地方在于璧疗,此時的程序是將Person類的實(shí)例化對象(內(nèi)存地址坯辩、屬性的參數(shù))傳遞到了change()方法中,由于傳遞的是一個Person對象類型崩侠,那么change()接收的也是Person類型漆魔。
- 引用傳遞可以發(fā)生在方法上,要觀察方法里面?zhèn)鞯牡膮?shù)類型却音,同時也要觀察方法的執(zhí)行過程改抡。
課時7:引用傳遞與垃圾產(chǎn)生分析
所有的引用傳遞的本質(zhì)是一場堆內(nèi)存的調(diào)戲游戲,那么也會造成辣雞的產(chǎn)生系瓢,針對辣雞產(chǎn)生原因產(chǎn)生簡單分析:
-
一個成功的引用傳遞
- 此時原本per2的堆內(nèi)存空間沒有棧內(nèi)存的指向了阿纤,(變成了辣雞)
- 所有的辣雞都被GC(Garbage Collector)收集器不定期回收并且釋放內(nèi)存空間
- 辣雞越多會影響GC的處理性能
- 一個棧內(nèi)存只能保存一個堆內(nèi)存的地址數(shù)據(jù),如果發(fā)生更改夷陋,則之前的地址數(shù)據(jù)將從此棧內(nèi)存中徹底消失**
第二章 深入分析類與對象
課時8:成員屬性封裝
在類之中的組成就是屬性與方法欠拾,一般而言方法都是對外提供服務(wù)的,需要有較高的安全性骗绕,需要進(jìn)行保護(hù)藐窄,需要采用封裝性對屬性進(jìn)行保護(hù)。
-
反例:類內(nèi)部屬性不封裝時爹谭,類外部能修改屬性
-
封裝后枷邪,類外部不能訪問其屬性,但是對類內(nèi)部可見诺凡。
下面代碼會報錯东揣,因?yàn)檫M(jìn)行了類外部不能訪問類內(nèi)部封裝好的屬性。
【setter腹泌、getter】設(shè)置或取得屬性可以使用setXxx()嘶卧、getXxx()方法
以
private String name
為例設(shè)置屬性方法
public void setName(String n)
-
獲取屬性方法
public String getName()
在需要對傳入屬性的獲取判斷時,在setXxx()里面添加條件判斷閉并進(jìn)一步修改值
- 類中的所有屬性都必須使用private封裝
- 訪問屬性必須setXxx() getXxx()
課時9:構(gòu)造方法與匿名對象
現(xiàn)在的程序在使用類的時候一般都按照了如下的步驟進(jìn)行:
- 聲明并實(shí)例化對象凉袱,這個時候?qū)嵗瘜ο笾械膶傩圆]有任何的的數(shù)據(jù)存在芥吟,都是其對應(yīng)數(shù)據(jù)類型的默認(rèn)值侦铜。
- 需要通過一系列的setter()方法設(shè)置屬性值
傳統(tǒng)調(diào)用:
這樣的調(diào)用很麻煩,每次都要setter getter钟鸵,所以可以通過構(gòu)造方法實(shí)現(xiàn)實(shí)例化對象中的屬性初始化處理钉稍,只有在關(guān)鍵字new的時候使用構(gòu)造方法。
- 構(gòu)造方法名稱必須與類名稱保持一致
- 構(gòu)造方法不允許設(shè)置任何返回值類型棺耍,沒有返回值定義
-
構(gòu)造方法時關(guān)鍵字new實(shí)例化對象的時候自動調(diào)用的
Person per = new Person("Tom",18);//調(diào)用有參構(gòu)造
- 每個類都會提供構(gòu)造方法贡未,如果沒有定義構(gòu)造方法,那么默認(rèn)的是無參的構(gòu)造方法蒙袍,是程序編譯的時候自動創(chuàng)建的俊卤。
- 如果這個類的構(gòu)造方法已經(jīng)明確在類中定義了,那么這個默認(rèn)的構(gòu)造方法將不會被自己創(chuàng)建害幅。比如類中明確定義了有參消恍,但是類外調(diào)用的是無參構(gòu)造,那么就會報構(gòu)造器參數(shù)的錯以现。
疑問:為什么構(gòu)造方法不設(shè)置返回值類型狠怨;如果不返回數(shù)據(jù),為什么不用void定義方法呢叼风?
- 編譯器是根據(jù)代碼結(jié)構(gòu)進(jìn)行編譯的(突然想學(xué)《編譯原理》)取董,執(zhí)行的時候也是根據(jù)代碼結(jié)構(gòu)執(zhí)行。
- 如果是void无宿,那么此結(jié)構(gòu)就與普通方法定義相同了,編譯器會認(rèn)為跟普通方法是一樣的枢里。
- 然而構(gòu)造方法是實(shí)例化對象的是時候調(diào)用的孽鸡,而普通方法是對象產(chǎn)生之后調(diào)用的。
構(gòu)造方法重載
升序或降序定義構(gòu)造函數(shù):構(gòu)造方法 | setter getter |
---|---|
在實(shí)例化對象的時候設(shè)置對象的屬性 | 除了擁有設(shè)置屬性的功能栏豺,還有修改屬性的功能 |
實(shí)例化對象的創(chuàng)建步驟:
- 定義對象名稱:
類名稱 對象名稱 = null
- 實(shí)例化對象:
對象名稱 = new 類名稱()
所以:只通過實(shí)例化對象進(jìn)行類的操作也是可以的彬碱,這種形式的對象叫做匿名對象
new Person("Tom",18).tell();
以上代碼通過對象進(jìn)行了tell()方法的調(diào)用,但是沒有任何的引用奥洼,所以使用過后會變成內(nèi)存辣雞巷疼,將被GC進(jìn)行辣雞回收與釋放。
以下代碼顯示了構(gòu)造方法(只要是方法)能傳遞數(shù)據(jù)類型(包括類)
class Message{
private String title;
public Message(String t) {
title = t;
}
public String getTitle() {
return title;
}
public void setTitle(String t) {
title = t;
}
}
class Person{
private String name;
private int age;
public Person(Message msg,int a ) {
name = msg.getTitle();
age = a;
}
public Message getInfo(){
return new Message(name + ":" + age)
}
public void tell() {
System.out.println("姓名" + name + "年齡" + age);
}
}
public class No1PersonMessage {
public static void main(String args[]) {
Message msg = new Message("mldn");
Person per = new Person(msg,20);
msg = per.getInfo();
System.out.println(msg.getTitle());
}
}
第三章 this關(guān)鍵字
課時10:this調(diào)用本類屬性
this有三類結(jié)構(gòu)
-
當(dāng)前類中的屬性:
this.屬性
-
當(dāng)前類中的方法(普通方法灵奖,構(gòu)造方法):
this()嚼沿,this.方法名稱();
- 描述當(dāng)前對象
setter getter
方法可以對屬性進(jìn)行賦值瓷患,但是在賦值的時候骡尽,采用的是如下的格式:
在Java程序之中“{ }”是作為結(jié)構(gòu)體的邊界符,那么在程序里面進(jìn)行變量(參數(shù)擅编、屬性都成為變量)使用的時候都會以“{ }”作為一個查找邊界(作用域)攀细,按照就近取用的原則箫踩,此時的構(gòu)造方法并沒有能夠訪問類中的屬性,所以為了明確標(biāo)記類中的屬性和參數(shù)的區(qū)別谭贪,往往會在屬性前追加一個
this
境钟,表示本類的屬性。所以只要是訪問本類中的屬性的時候俭识,都要加
this
public Person(String n,int a) {
this.name = n;
this.age = a;
}
public void tell() {
System.out.println("姓名:" + this.name + "吱韭、年齡:" + this.age);
}
課時11:this調(diào)用本類方法
- 構(gòu)造方法調(diào)用:
this.()
使用關(guān)鍵字new實(shí)例化對象的時候才會調(diào)用構(gòu)造方法 - 普通方法調(diào)用:
this.名稱()
實(shí)例化對象產(chǎn)生之后就可以調(diào)用普通方法
構(gòu)造方法調(diào)用this.setter
方法 實(shí)現(xiàn)屬性賦值