面向?qū)ο蠡A(chǔ)
一求厕、面向?qū)ο蟮母拍睿?/h4>
站在更高的層次美浦,省略我們自己對(duì)細(xì)節(jié)的關(guān)注,讓對(duì)象替我們完成具體的工作荤牍。我們只需要“使喚”對(duì)象即可康吵。面對(duì)更復(fù)雜的場(chǎng)景,我們可以輕易組織對(duì)象應(yīng)對(duì)更靈活惭载、更多的變化,同時(shí)可以提高代碼的復(fù)用性含长。舉例好比我們招來“管家”拘泞、“秘書”、“保姆”诗鸭,我們指揮管家,管家指揮保姆请唱,保姆完成最后做飯的工作十绑,對(duì)應(yīng)實(shí)際項(xiàng)目中本橙,則是通過對(duì)象指揮其他對(duì)象,最終完成工作亏狰,我們更多則關(guān)注如何設(shè)計(jì)對(duì)象,以及組織對(duì)象之間的工作策州,涉及架構(gòu)問題。
二孽糖、類與對(duì)象:
要讓對(duì)象能夠替我們完成工作,就要設(shè)計(jì)出類誉尖,按照類來創(chuàng)建對(duì)象,類就好比圖紙探熔,對(duì)象則是按照?qǐng)D紙生產(chǎn)出來的產(chǎn)品柬甥,包含數(shù)據(jù)和方法其垄。類必須通過對(duì)象來使用苛蒲,不能拿著“圖紙”就去干活兒。但是我們也不能直接使用對(duì)象绿满,最終能操縱的是一個(gè)對(duì)象的引用(reference)臂外。在這里有一個(gè)很形象的比喻:你可以把車鑰匙和車看作是一組對(duì)象引用和對(duì)象的組合。當(dāng)你想要開車的時(shí)候喇颁,你首先需要拿出車鑰匙點(diǎn)擊開鎖的選項(xiàng)漏健,停車時(shí)橘霎,你需要點(diǎn)擊加鎖來鎖車谭溉。車鑰匙相當(dāng)于就是引用,車就是對(duì)象,由車鑰匙來驅(qū)動(dòng)車的加鎖和開鎖城丧。并且愿卸,即使沒有車的存在,車鑰匙也是一個(gè)獨(dú)立存在的實(shí)體园骆,也就是說滋捶,你有一個(gè)對(duì)象引用垮衷,但你不一定需要一個(gè)對(duì)象與之關(guān)聯(lián)仰迁,也就是說可以創(chuàng)建一個(gè)空的引用,在需要時(shí)與對(duì)象進(jìn)行關(guān)聯(lián)再使用。
類必須存在.java文件中县恕,一個(gè)文件可以存在N個(gè)類师坎,但是只能存在一個(gè)public修飾的類作為主類犯眠,類名與文件名保持一致。
類由屬性和方法組成:
- 屬性:就相當(dāng)于人的一個(gè)個(gè)的特征
- 方法:就相當(dāng)于人的一個(gè)個(gè)的行為泉瞻,例如:說話、吃飯芹啥、唱歌梆暮、睡覺
類定義格式:
class 類名稱{
成員屬性
成員方法
}
屬性與方法:
屬性定義格式:
數(shù)據(jù)類型 屬性名;
屬性定義并賦值的格式:
數(shù)據(jù)類型 屬性名 = 初始化值;
方法定義格式:
權(quán)限修飾符 返回值類型 方法名(形式參數(shù)列表){
//方法體
return 返回值铣揉;
}
通過對(duì)象使用:
類名稱 對(duì)象名稱 = new 類名稱() ; //創(chuàng)建引用并與對(duì)象進(jìn)行關(guān)聯(lián)
訪問類中的屬性: 對(duì)象.屬性 ;
調(diào)用類中的方法: 對(duì)象.方法(實(shí)際參數(shù)列表) ;
三、創(chuàng)建對(duì)象內(nèi)存分析:
1讲婚、棧
棧內(nèi)存通過 '棧指針' 來創(chuàng)建空間與釋放空間,指針向下移動(dòng), 會(huì)創(chuàng)建新的內(nèi)存, 向上移動(dòng), 會(huì)釋放這些內(nèi)存错维,這種移動(dòng)的方式, 必須要明確移動(dòng)的大小與范圍械筛,這是一個(gè)對(duì)于數(shù)據(jù)存儲(chǔ)的限制, 存儲(chǔ)的數(shù)據(jù)大小是固定的 , 影響了程序 的靈活性晨逝,也就是說通過類設(shè)計(jì)的對(duì)象永遠(yuǎn)不會(huì)存儲(chǔ)在棧內(nèi)存中。
只能存儲(chǔ)基本數(shù)據(jù)類型冬念,引用數(shù)據(jù)類型的引用趁窃。
棧內(nèi)存存取速度非常快刘急,僅次于寄存器棚菊。Java中棧區(qū)的大小約為2M浸踩。
2叔汁、堆
存放對(duì)象,通過new關(guān)鍵字創(chuàng)建的變量检碗,通過new關(guān)鍵字通知虛擬機(jī)在堆內(nèi)存中開辟一塊空間据块,其中內(nèi)存的釋放由GC負(fù)責(zé)。GC回收的原則是折剃,棧內(nèi)存中不存在此對(duì)象的引用時(shí)另假,則視其為垃圾,進(jìn)行回收怕犁。堆內(nèi)存與棧內(nèi)存不同, 優(yōu)點(diǎn)在于我們創(chuàng)建對(duì)象時(shí) , 不必關(guān)注堆內(nèi)存中需要開辟多少存儲(chǔ)空間 , 也不需要關(guān)注內(nèi)存占用時(shí)長(zhǎng)边篮。
3、方法區(qū)
存放類奏甫、靜態(tài)變量戈轿、常量、成員方法阵子,常量池中包含static修飾的成員思杯,字符串常量池后來移動(dòng)到堆內(nèi)存中。
4挠进、PC寄存器
PC寄存器保存的是 當(dāng)前正在執(zhí)行的 JVM指令的 地址色乾。在Java程序中, 每個(gè)線程啟動(dòng)時(shí), 都會(huì)創(chuàng)建一個(gè)PC寄存器誊册。
5、本地方法棧
保存本地(native)方法的地址暖璧。一個(gè)Native Method就是一個(gè)Java調(diào)用非java代碼的接口案怯。一個(gè)Native Method是這樣一個(gè)java的方法:該方法的實(shí)現(xiàn)由非java語言實(shí)現(xiàn),比如C漆撞。這個(gè)特征并非java所特有殴泰,很多其它的編程語言都有這一機(jī)制,比如在C++中浮驳,你可以用extern "C"告知C++編譯器去調(diào)用一個(gè)C的函數(shù)悍汛。
四、構(gòu)造方法
作用: 用于對(duì)象初始化至会。
執(zhí)行時(shí)機(jī): 在創(chuàng)建對(duì)象時(shí),自動(dòng)調(diào)用
特點(diǎn): 所有的Java類中都會(huì)至少存在一個(gè)構(gòu)造方法 如果一個(gè)類中沒有明確的編寫構(gòu)造方法, 則編譯器會(huì)自動(dòng)生成一個(gè)無參的構(gòu)造方法, 構(gòu)造方法中沒有任何的代 碼离咐! 如果自行編寫了任意一個(gè)構(gòu)造器, 則編譯器不會(huì)再自動(dòng)生成無參的構(gòu)造方法。
推薦提供一個(gè)無參數(shù)構(gòu)造函數(shù)與全參數(shù)構(gòu)造方法奉件,將初始化內(nèi)容放置其中宵蛀,在創(chuàng)建對(duì)象時(shí)自動(dòng)調(diào)用。建議自定義無參構(gòu)造方法县貌,不要對(duì)編譯器形成依賴术陶,避免錯(cuò)誤發(fā)生。 當(dāng)類中有非常量成員變量時(shí)煤痕,建議提供兩個(gè)版本的構(gòu)造方法梧宫,一個(gè)是無參構(gòu)造方法,一個(gè)是全屬性做參數(shù)的構(gòu)造方法摆碉。 當(dāng)類中所有成員變量都是常量或者沒有成員變量時(shí)塘匣,建議不提供任何版本的構(gòu)造。
構(gòu)造器初始化:
對(duì)成員屬性可以進(jìn)行默認(rèn)字段的初始化巷帝,如基本類型的初始化忌卤,與引用數(shù)據(jù)類型的初始化默認(rèn)值,也可以指定數(shù)值初始化楞泼。
初始化順序:
靜態(tài)屬性初始化驰徊,靜態(tài)方法塊初始化,普通屬性初始化堕阔,普通方法塊初始化棍厂,構(gòu)造函數(shù)初始化。
public class LifeCycle {
private static String staticField = getStaticField();
static {
System.out.println(staticField);
System.out.println("靜態(tài)方法初始快");
}
private String field = getField();
{
System.out.println(field);
}
public LifeCycle() {
System.out.println("構(gòu)造函數(shù)初始化");
}
public static String getStaticField() {
String statiFiled = "Static Field Initial";
return statiFiled;
}
public static String getField() {
String filed = "Field Initial";
return filed;
}
public static void main(String[] argc) {
new LifeCycle();
}
}
五印蔬、方法的重載
兩個(gè)方法的名稱相同勋桶,參數(shù)列表的類型或數(shù)目或順序不同(方法簽名不同),即可完成重載,實(shí)際工作時(shí)例驹,編譯器會(huì)自己選擇最合適的那個(gè)方法捐韩。注意,返回值不是方法簽名的一部分鹃锈,僅返回值類型不同荤胁,不能算作重載,參數(shù)列表的長(zhǎng)度或類型不同即可完成方法的重載屎债。注意區(qū)分重載與重寫仅政,重寫是子類對(duì)父類的方法進(jìn)行子類的實(shí)現(xiàn),而重載是在同一個(gè)類中的盆驹,重寫過程中方法的簽名是完全一致不可以改變的圆丹,只有實(shí)現(xiàn)的邏輯是不一樣的。編譯器會(huì)在重寫處標(biāo)注(Override)躯喇,重載則是Overload辫封。
重載的條件:
- 方法名稱必須相同。
- 參數(shù)列表必須不同(個(gè)數(shù)不同廉丽、或類型不同倦微、參數(shù)類型排列順序不同等)。方法的返回類型可以相同也可以不相同正压。
- 僅僅返回類型不同不足以成為方法的重載欣福。
- 重載是發(fā)生在編譯時(shí)的,因?yàn)榫幾g器可以根據(jù)參數(shù)的類型來選擇使用哪個(gè)方法焦履。
重寫的原則:
- 重寫的方法必須要和父類保持一致拓劝,包括返回值類型,方法名,參數(shù)列表也都一樣〔昧迹·重寫的方法可以使用@0verride注解來標(biāo)識(shí)
- 子類中重寫方法的訪問權(quán)限不能低于父類中方法的訪問權(quán)限凿将。
六校套、匿名對(duì)象
如果本對(duì)象只使用一次价脾,可以使用匿名對(duì)象。反之笛匙,如果對(duì)象的使用至少2次侨把,則必須有引用指向這個(gè)對(duì)象,否則創(chuàng)建之后就找不到了妹孙。匿名對(duì)象只能使用一次秋柄,因?yàn)闆]有任何的對(duì)象引用,所以將稱為垃圾蠢正,等待被G·C回收骇笔。 只使用一次的對(duì)象可以通過匿名對(duì)象的方式完成,這一點(diǎn)在以后的開發(fā)中將經(jīng)常使用到。
七笨触、面向?qū)ο蟮娜筇卣?/h4>
封裝懦傍、繼承、多態(tài)芦劣。
面向?qū)ο筮M(jìn)階
一粗俱、封裝
隱藏類中的數(shù)據(jù)域,對(duì)類中的數(shù)據(jù)屬性進(jìn)行封裝虚吟,提供訪問器與更改器進(jìn)行數(shù)據(jù)的操作寸认。建議在類的設(shè)計(jì)中,對(duì)所有屬性進(jìn)行封裝串慰,并為其提供setter及getter方法進(jìn)行設(shè)置和取得操作偏塞。
class Person{
private String name ; // 表示姓名
private int age ; // 表示年齡
void tell(){
System.out.println("姓名:" + getName() + ";年齡:" + getAge()) ;
}
public void setName(String str){
name = str ;
}
public void setAge(int a){
if(a>0&&a<150)
age = a ;
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
};
二邦鲫、this與super關(guān)鍵字
this指向當(dāng)前創(chuàng)建的對(duì)象烛愧,可以使用this完成屬性的訪問,調(diào)用方法掂碱,避免由于方法參數(shù)與類中屬性重名而導(dǎo)致方法的工作異常怜姿。如果你把 this 理解為指向自身的一個(gè)引用,那么super就是指向父類的一個(gè)引用疼燥。super關(guān)鍵字和 this一樣沧卢,你可以使用super.對(duì)象來引用父類的成員,super(參數(shù))調(diào)用父類的構(gòu)造函數(shù)醉者。
三但狭、static靜態(tài)
可修飾:代碼塊、成員變量撬即、成員方法立磁。
被static修飾的成員變量與成員方法稱為類屬性與類方法,在類加載時(shí)即可使用剥槐,不需要?jiǎng)?chuàng)建對(duì)象完成調(diào)用唱歧,使用類名即可調(diào)用。在內(nèi)存中粒竖,均存儲(chǔ)在方法區(qū)颅崩,為所有對(duì)象所共有,只存儲(chǔ)一份蕊苗,不會(huì)隨多個(gè)對(duì)象的創(chuàng)建而產(chǎn)生多個(gè)內(nèi)存中的副本沿后。
靜態(tài)可以不可訪問非靜態(tài),而非靜態(tài)能訪問靜態(tài)朽砰,原因是對(duì)象不一定已經(jīng)創(chuàng)建尖滚,使用靜態(tài)可能是類加載時(shí)期喉刘,沒有創(chuàng)建具體對(duì)象是不能訪問非靜態(tài)的。
四漆弄、代碼塊
1饱搏、構(gòu)造代碼塊
在類中的成員代碼塊, 我們稱其為構(gòu)造代碼塊置逻, 在每次對(duì)象創(chuàng)建時(shí)執(zhí)行推沸, 執(zhí)行在構(gòu)造方法之前∪耄可以隨對(duì)象的創(chuàng)建反復(fù)執(zhí)行多次鬓催。
2、靜態(tài)代碼塊
在類中使用static修飾的成員代碼塊恨锚, 我們稱其為靜態(tài)代碼塊宇驾, 在類加載時(shí)執(zhí)行。 每次程序啟動(dòng)到關(guān)閉 猴伶,只會(huì)執(zhí)行一次的代碼塊炬称。
構(gòu)造順序:靜態(tài)代碼塊 --> 構(gòu)造代碼塊 --> 構(gòu)造方法
五涩搓、權(quán)限修飾符:
繼承:
繼承是所有0OP(Object Oriented Programming)語言和Java語言都不可或缺的一部分掰邢。只要我們創(chuàng)建了一個(gè)類界弧,就隱式的繼承自0bject父類,只不過沒有指定办桨。如果你顯示指定了父類筹淫,那么你繼承于父類,而你的父類繼承于Object類呢撞。繼承雙方具有屬性上的共性损姜,并可能發(fā)生方法的重寫。
組合:
組合其實(shí)不難理解殊霞,就是將對(duì)象引用置于新類中即可摧阅。組合也是一種提高類的復(fù)用性的一種方式。如果你想讓類具有更多的擴(kuò)展功能绷蹲,你需要記住一句話多用組合棒卷,少用繼承。
public class SoccerPlayer {
private String name;
private Soccer soccer;
}
public class Soccer {
private String soccerName;
}
繼承與組合的區(qū)別:
代理:
除了繼承和組合外瘸右,另外一種值得探討的關(guān)系模型稱為代理娇跟。代理的大致描述是岩齿,A想要調(diào)用B類的方法太颤,A不直接調(diào)用,A會(huì)在自己的類中創(chuàng)建一個(gè)B對(duì)象的代理盹沈,再由代理調(diào)用B的方法龄章。
六吃谣、單例模式
單例設(shè)計(jì)模式:保證程序在內(nèi)存中只有一個(gè)對(duì)象存在(被程序所共享)
1、懶漢式
//隨著類的加載在內(nèi)存中對(duì)象為null做裙,當(dāng)調(diào)用 getInstance 方法時(shí)才創(chuàng)建對(duì)象(延遲加載)
class Single{
private Single(){}
private static Single s1 = null;
public static Single getInstance(){
if(s1 == null){
s1 = new Single();
}
return s1;
}
}
2岗憋、餓漢式
//隨著類的加載直接創(chuàng)建對(duì)象(推薦開發(fā)中使用)
class Single2{
private Single2(){}
private static Single2 s = new Single2();
public static Single getInstance(){
return s;
}
void print(){
System.out.println("Hello World!");
}
}
實(shí)現(xiàn)步驟:
- 保證一個(gè)類只有一個(gè)實(shí)例,實(shí)現(xiàn)方式:構(gòu)造方法私有化
- 必須要自己創(chuàng)建這個(gè)實(shí)例锚贱,實(shí)現(xiàn)方式:在本類中維護(hù)一個(gè)本類對(duì)象(私有仔戈,靜態(tài))
- 必須向整個(gè)程序提供這個(gè)實(shí)例,實(shí)現(xiàn)方式:對(duì)外提供公共的訪問方式(getInstance方法拧廊,靜態(tài))
七监徘、包
1、簡(jiǎn)介
把功能相似或相關(guān)的類或接口組織在同一個(gè)包中吧碾,方便類的查找和使用凰盔。 包如同文件夾一樣,不同的包中的類的名字是可以相同的倦春,當(dāng)同時(shí)調(diào)用兩個(gè)不同包中相同類名的類時(shí)户敬,應(yīng)該加上包名加以區(qū)別。因此睁本,包可以避免名字沖突尿庐。包也限定了訪問權(quán)限,擁有包訪問權(quán)限的類才能訪問某個(gè)包中的類呢堰。
2屁倔、使用規(guī)則
- 包中java文件的定義:
在.java文件的首部, 必須編寫類所屬哪個(gè)包暮胧, 格式:
package 包名;
- 包的定義:
通常由多個(gè)單詞組成锐借, 所有單詞的字母小寫, 單詞與單詞之間使用.隔開 往衷,一般命名為“com.公司名.項(xiàng)目名.模塊名....”钞翔。
規(guī)范由來:
由于Java面向?qū)ο蟮奶匦裕棵鸍ava開發(fā)人員都可以編寫屬于自己的Java Package席舍,為了保障每個(gè)JavaPackage命名的唯一性布轿,在最新的Java編程規(guī)范中,要求開發(fā)人員在自己定義的包名前加上唯一的前綴来颤。由于互聯(lián)網(wǎng)上的域名稱是不會(huì)重復(fù)的汰扭,所以多數(shù)開發(fā)人員采用自己公司在互聯(lián)網(wǎng)上的域名稱作為自己程序包的唯一前綴。例如:com.java.xxx
導(dǎo)入包中的某個(gè)類:
import 包名.類名;
八福铅、main方法詳解:
main()方法一直寫到了今天:
public static void main(String args[])
以上的各個(gè)參數(shù)的含義如下:
· public:表示公共的內(nèi)容萝毛,可以被所有操作所調(diào)用
· static:表示方法是靜態(tài)的,可以由類名稱直接調(diào)用滑黔。java StaticDemo09
· void:表示沒有任何的返回值操作
· main:系統(tǒng)規(guī)定好的方法名稱笆包。如果main寫錯(cuò)了或沒有环揽,會(huì)報(bào)錯(cuò):NoSuchMethodError: main
· String[] args:字符串?dāng)?shù)組,接收參數(shù)的
所有的參數(shù)在執(zhí)行類的時(shí)候以空格進(jìn)行分割庵佣。
java StaticDemo10 1 2 3 4 5 6 7
但是歉胶,要輸入的是以下幾種參數(shù)"hello world"、"hello vince"巴粪、"hello mjw"通今。
因?yàn)橐钥崭穹指睿砸陨系娜M參數(shù)會(huì)當(dāng)做六組參數(shù)輸入肛根,那么此時(shí)如果要想完成有空格的內(nèi)容輸入衡创,則參數(shù)需
要使用""括起來。
java StaticDemo10 "hello world" "hello vince" "hello mjw"
九晶通、final的用法
- final的意思是最后的璃氢、最終的,它可以修飾類、屬性和方法狮辽。
- final修飾類時(shí)一也,表明這個(gè)類不能被繼承。final類中的成員變量可以根據(jù)需要設(shè)為final喉脖,但是要注意final類中的所有成員方法都會(huì)被隱式地指定為final方法椰苟。
- final修飾方法時(shí),表明這個(gè)方法不能被任何子類重寫树叽,因此舆蝴,如果只有在想明確禁止該方法在子類中被覆蓋的情況下才將方法設(shè)置為final。
- final修飾變量分為兩種情況题诵,一種是修飾基本數(shù)據(jù)類型洁仗,表示數(shù)據(jù)類型的值不能被修改;一種是修飾引用類型,表示對(duì)其初始化之后便不能再讓其指向另一個(gè)對(duì)象性锭。
面向?qū)ο蟾呒?jí)
一赠潦、抽象類
//使用abstract class關(guān)鍵字聲明
//一個(gè)抽象類中可以沒有抽象方法。抽象方法必須寫在抽象類或者接口中草冈。
//抽象方法也要由abstract關(guān)鍵字聲明
abstract class 類名{ // 抽象類
public abstract void 方法名() ; // 抽象方法她奥,只聲明而未實(shí)現(xiàn)(沒有{}定義的方法體)的方法
}
注意:
- 抽象類不可以被實(shí)例化(細(xì)節(jié)都不確定,沒有辦法實(shí)例化)怎棱,無法通過new關(guān)鍵字進(jìn)行構(gòu)造哩俭。但是抽象類可以有構(gòu)造方法,子類繼承抽象類時(shí)拳恋,可以創(chuàng)建抽象類對(duì)象凡资,只不過是JVM幫助創(chuàng)建,由JVM進(jìn)行實(shí)例化诅岩,我們自己無法創(chuàng)建讳苦。子類對(duì)象實(shí)例化的時(shí)候的流程與普通類的繼承是一樣的带膜,都是要先調(diào)用父類中的構(gòu)造方法(默 認(rèn)是無參的)吩谦,之后再調(diào)用子類自己的構(gòu)造方法鸳谜。
- 繼承抽象類的子類必須重寫抽象類的所有抽象方法,只要還有一個(gè)抽象的方法沒有重寫實(shí)現(xiàn)式廷,則子類頁也必須聲明為抽象類咐扭。
- 抽象類不可以被final聲明:子類無從繼承,該抽象類無法被實(shí)現(xiàn)滑废。
- 抽象類必須使用public與protected進(jìn)行修飾蝗肪,默認(rèn)為public,否則private修飾下蠕趁,子類無法繼承薛闪。
二、接口
一個(gè)類中的全部方法都是抽象方法俺陋,全部屬性都是全局常量豁延,那么此時(shí)就可以將這個(gè)類定義成一個(gè)接口。使用interface關(guān)鍵字進(jìn)行聲明:
interface 接口名稱{
全局常量;
抽象方法;
}
面向接口編程思想:
接口是定義(規(guī)范腊状,約束)與實(shí)現(xiàn)(名實(shí)分離的原則)的分離诱咏,通過繼承接口來實(shí)現(xiàn)接口中的方法,完成實(shí)現(xiàn)缴挖。
優(yōu)點(diǎn):
- 降低程序的耦合性
- 易于程序擴(kuò)展
- 有利于程序維護(hù)
全局常量和抽象方法簡(jiǎn)寫:
JVM會(huì)自動(dòng)幫助我們完成袋狞,全局常量編寫時(shí), 可以省略public static final 關(guān)鍵字映屋,抽象方法編寫時(shí)苟鸯, 可以省略 public abstract 關(guān)鍵字。
1棚点、全局常量編寫時(shí)倔毙, 可以省略public static final 關(guān)鍵字,例如:
public static final String INFO = "內(nèi)容" ;
簡(jiǎn)寫后:
String INFO = "內(nèi)容" ;
2乙濒、抽象方法編寫時(shí)陕赃, 可以省略 public abstract 關(guān)鍵字, 例如:
public abstract void print() ;
簡(jiǎn)寫后:
void print() ;
接口的實(shí)現(xiàn):
實(shí)現(xiàn)時(shí)使用implements關(guān)鍵字實(shí)現(xiàn)颁股,java中的類只能單繼承類么库,但是可以對(duì)接口進(jìn)行多實(shí)現(xiàn),通過接口實(shí)現(xiàn)別的語言中的多繼承甘有。
class 子類 implements 父接口1,父接口2...{
}
接口的繼承:
允許對(duì)接口進(jìn)行多繼承诉儒,因?yàn)槎际浅橄蟮牟糠郑淮嬖诰唧w實(shí)現(xiàn):
interface C extends A,B{
}
注意:一個(gè)接口要想使用亏掀,必須依靠子類實(shí)現(xiàn)接口中的所有抽象方法忱反。
重點(diǎn):接口和抽象類的區(qū)別
- 抽象類要被子類繼承泛释,接口要被類實(shí)現(xiàn)。
- 接口只能聲明抽象方法温算,抽象類中可以聲明抽象方法怜校,也可以寫非抽象方法。
- 接口里定義的變量只能是公共的靜態(tài)的常量注竿,抽象類中的變量是普通變量茄茁。
- 抽象類使用繼承來使用, 無法多繼承巩割。 接口使用實(shí)現(xiàn)來使用裙顽, 可以多實(shí)現(xiàn)
- 抽象類中可以包含static方法 ,但是接口中不允許(靜態(tài)方法不能被子類重寫宣谈,因此接口中不能聲明靜態(tài)方法)
- 接口不能有構(gòu)造方法愈犹,但是抽象類可以有
- 可以用接口變量引用一個(gè)實(shí)現(xiàn)了接口的類對(duì)象。
三闻丑、多態(tài)
概念:
多態(tài):就是對(duì)象的多種表現(xiàn)形式漩怎,(多種體現(xiàn)形態(tài))
體現(xiàn):
- 父類變量可以引用父類和子類對(duì)象(對(duì)象多態(tài)性,向上轉(zhuǎn)型)梆掸。子類變量引用父類實(shí)例需要實(shí)現(xiàn)強(qiáng)轉(zhuǎn)扬卷。
- 方法的重載與重寫(方法的多態(tài))
重載與重寫的區(qū)別:
重載: 一個(gè)類中方法的多態(tài)性體現(xiàn) ,多個(gè)方法簽名酸钦,編譯器來選擇最合適的那個(gè)怪得。
重寫: 子父類中方法的多態(tài)性體現(xiàn)。調(diào)用繼承鏈上最近的子父類同名方法卑硫。
對(duì)象的類型轉(zhuǎn)換:
· 向上轉(zhuǎn)型:將子類實(shí)例變?yōu)楦割悓?shí)例
|- 格式:父類 父類對(duì)象 = 子類實(shí)例 徒恋;
· 向下轉(zhuǎn)型:將父類實(shí)例變?yōu)樽宇悓?shí)例
|- 格式:子類 子類對(duì)象 = (子類)父類實(shí)例 ;
四欢伏、insatnceof方法
給自定義類重寫equals方法時(shí)調(diào)用入挣,判斷某個(gè)對(duì)象是否為某個(gè)類的實(shí)例,返回boolean類型的值硝拧。
五径筏、Object類
所有類的父類,自定義類繼承自O(shè)bject障陶,需要重寫toString與equals和hashcode三個(gè)方法滋恬,后兩個(gè)配合使用。
使用Object可以接收任意的引用數(shù)據(jù)類型抱究。(多態(tài))
toString
建議重寫Object中的toString方法恢氯。 此方法的作用:返回對(duì)象的字符串表示形式。
Object的toString方法, 返回對(duì)象的內(nèi)存地址
equals
建議重寫Object中的equals(Object obj)方法勋拟,此方法的作用:指示某個(gè)其他對(duì)象是否“等于”此對(duì)象勋磕。
Object的equals方法:實(shí)現(xiàn)了對(duì)象上最具區(qū)別的可能等價(jià)關(guān)系; 也就是說,對(duì)于任何非空引用值x和y 敢靡,當(dāng)且僅當(dāng)x和y引用同一對(duì)象( x == y具有值true )時(shí)挂滓,此方法返回true 。
equals方法重寫時(shí)的五個(gè)特性:
自反性 :對(duì)于任何非空的參考值x 醋安, x.equals(x)應(yīng)該返回true 杂彭。
對(duì)稱性 :對(duì)于任何非空引用值x和y 墓毒, x.equals(y)應(yīng)該返回true當(dāng)且僅當(dāng)y.equals(x)回報(bào)true 吓揪。
傳遞性 :對(duì)于任何非空引用值x , y和z 所计,如果x.equals(y)回報(bào)true個(gè)y.equals(z)回報(bào)true 柠辞,然后
x.equals(z)應(yīng)該返回true 。
一致性 :對(duì)于任何非空引用值x和y 主胧,多次調(diào)用x.equals(y)始終返回true或始終返回false 叭首,前提是未修改對(duì)象
上的equals比較中使用的信息。
非空性 :對(duì)于任何非空的參考值x 踪栋, x.equals(null)應(yīng)該返回false 焙格。
六、內(nèi)部類(非重點(diǎn))
概念:定義在別的類內(nèi)部的類夷都。由于每個(gè)類都會(huì)產(chǎn)生一個(gè).class文件眷唉,其中包含了如何創(chuàng)建該類型的對(duì)象的全部信息,那么囤官,如何表示內(nèi)部類的信息呢?可以使用美元符號(hào)來表示冬阳,比如OuterClass美元符號(hào)InnerClass.class。這里InnerClass就是OuterClass 的一個(gè)內(nèi)部類党饮。也就是說肝陪,每個(gè)內(nèi)部類都能獨(dú)立地繼承一個(gè)(接口的)實(shí)現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn)刑顺,對(duì)于內(nèi)部類都沒有影響氯窍。這也是隱藏了內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。內(nèi)部類擁有外部類的訪問權(quán)蹲堂。在這段代碼中狼讨,InnerClass就是OuterClass 的一個(gè)內(nèi)部類。也就是說贯城,每個(gè)內(nèi)部類都能獨(dú)立地繼承一個(gè)(接口的)實(shí)現(xiàn)熊楼,所以無論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒有影響。這也是隱藏了內(nèi)部實(shí)現(xiàn)細(xì)節(jié)鲫骗。內(nèi)部類擁有外部類的訪問權(quán)犬耻。內(nèi)部類不僅僅能夠定義在類的內(nèi)部,還可以定義在方法和作用域內(nèi)部执泰,這種被稱為局部?jī)?nèi)部類枕磁,除此之外,還有匿名內(nèi)部類术吝、內(nèi)部類可以實(shí)現(xiàn) Java 中的 多重繼承计济。下面是定義內(nèi)部類的方式
1、成員內(nèi)部類
class Outer {
private double x = 0;
public Outer(double x) {
this.x = x;
}
class Inner { //內(nèi)部類
private double x = 1.0
public void say() {
System.out.println("x="+x);//默認(rèn)使用的是內(nèi)部類的x,打印1.0
System.out.println("x="+Outer.this.x);//使用的是外部類的x,打印0
}
}
}
特點(diǎn): 成員內(nèi)部類可以無條件訪問外部類的所有成員屬性和成員方法(包括private成員和靜態(tài)成員)排苍,因?yàn)橥獠款惒粍?chuàng)建對(duì)象沦寂,內(nèi)部類是實(shí)現(xiàn)不了的,當(dāng)內(nèi)部類可以使用時(shí)淘衙,外部類的成員與方法都已經(jīng)有了传藏。
Outer o = new Outer();
Outer.Inner i = o.new Inner();//使用內(nèi)部類
當(dāng)成員內(nèi)部類擁有和外部類同名的成員變量或者方法時(shí),會(huì)發(fā)生隱藏現(xiàn)象彤守,即默認(rèn)情況下訪問的是成員內(nèi)部類的成員毯侦。
如果要訪問外部類的同名成員,需要以下面的形式進(jìn)行訪問:
**外部類.this.成員變量 **
外部類.this.成員方法
2具垫、局部?jī)?nèi)部類
局部?jī)?nèi)部類是定義在一個(gè)方法或者一個(gè)作用域里面的類侈离,它和成員內(nèi)部類的區(qū)別在于局部?jī)?nèi)部類的訪問僅限于方法內(nèi)或 者該作用域內(nèi)。
注意:局部?jī)?nèi)部類就像是方法里面的一個(gè)局部變量一樣筝蚕,是不能有public卦碾、protected、private以及static修飾符的饰及。
3蔗坯、匿名內(nèi)部類
匿名內(nèi)部類由于沒有名字,所以它的創(chuàng)建方式有點(diǎn)兒奇怪燎含。創(chuàng)建格式如下:
new 父類構(gòu)造器(參數(shù)列表)|實(shí)現(xiàn)接口()
{
//匿名內(nèi)部類的類體部分
}
在這里我們看到使用匿名內(nèi)部類我們必須要繼承一個(gè)父類或者實(shí)現(xiàn)一個(gè)接口宾濒,當(dāng)然也僅能只繼承一個(gè)父類或者實(shí)現(xiàn)一個(gè)接口。同時(shí)它也是沒有class關(guān)鍵字屏箍,這是因?yàn)槟涿麅?nèi)部類是直接使用new來生成一個(gè)對(duì)象的引用绘梦。當(dāng)然這個(gè)引用是隱式的。
注意:
- 使用匿名內(nèi)部類時(shí)赴魁,我們必須是繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口卸奉,但是兩者不可兼得,同時(shí)也只能繼承一個(gè)類或 者實(shí)現(xiàn)一個(gè)接口颖御。
- 匿名內(nèi)部類中是不能定義構(gòu)造函數(shù)的榄棵。
- 匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法。
- 匿名內(nèi)部類為局部?jī)?nèi)部類,所以局部?jī)?nèi)部類的所有限制同樣對(duì)匿名內(nèi)部類生效疹鳄。
- 匿名內(nèi)部類不能是抽象的拧略,它必須要實(shí)現(xiàn)繼承的類或者實(shí)現(xiàn)的接口的所有抽象方法。
- 只能訪問final型的局部變量(單獨(dú)編譯為字節(jié)碼文件瘪弓,如果不是final垫蛆,會(huì)造成引用與拷貝不一致的問題)
4、靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類也是定義在另一個(gè)類里面的類腺怯,只不過在類的前面多了一個(gè)關(guān)鍵字static袱饭。 靜態(tài)內(nèi)部類是不需要依賴于外部類對(duì)象的(不需要先創(chuàng)建外部類實(shí)例),這點(diǎn)和類的靜態(tài)成員屬性有點(diǎn)類似呛占,并且它不能使用外部類的非static成員變量或者方法(靜態(tài)不能訪問非靜態(tài))虑乖,因?yàn)榇藭r(shí)內(nèi)部已經(jīng)有了,外部可能還沒有栓票。
public class Test {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
}
class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}
七决左、包裝類
自動(dòng)裝箱與自動(dòng)拆箱:
Float f = 10.3f ; // 自動(dòng)裝箱
float x = f ; // 自動(dòng)拆箱
System.out.println(f * f) ; // 直接利用包裝類完成
System.out.println(x * x) ; // 直接利用包裝類完成
字符串裝換:
//使用包裝類還有一個(gè)很優(yōu)秀的地方在于:可以將一個(gè)字符串變?yōu)橹付ǖ幕緮?shù)據(jù)類型愕够,此點(diǎn)一般在接收輸入數(shù)據(jù)上使用較多走贪。
//在Integer類中提供了以下的操作方法:
public static int parseInt(String s) :將String變?yōu)閕nt型數(shù)據(jù)
//在Float類中提供了以下的操作方法:
public static float parseFloat(String s) :將String變?yōu)镕loat
//在Boolean 類中提供了以下操作方法:
public static boolean parseBoolean(String s) :將String變?yōu)閎oolean
八、可變參數(shù)
返回值類型 方法名稱(數(shù)據(jù)類型…參數(shù)名稱){
//參數(shù)在方法內(nèi)部 惑芭, 以數(shù)組的形式來接收
}
int calculateSum(int...nums){//nums為長(zhǎng)度不限的可變參數(shù)坠狡,注意可變參數(shù)一定在參數(shù)列表的最后
int sum = 0;
for(int num:nums){
n += num;
}
return sum;
}
九、遞歸
函數(shù)要調(diào)用自身遂跟,程序要有出口逃沿。