1.toString方法
- object中定義有toString()方法匣椰,其返回值是string類型裆熙,它描述的是當(dāng)前對象的有關(guān)信息。
- 在進(jìn)行string與其他類型數(shù)據(jù)的連接操作時(如system.out.println(“info”+person))禽笑,將自動調(diào)用該對象的toString()方法入录。
- 可以根據(jù)用戶需要重寫toString()方法。
2.equals方法
- public boolean equals(object obj)方法提供定義對象是否“相等”的邏輯佳镜。
- object的equals()方法定義為:x.equals(y) 當(dāng)x和y是同一個對象的引用時僚稿,返回true,否則返回false蟀伸。
- j2se提供的一些類蚀同,如String Date等,重寫object的equals()方法啊掏,調(diào)用這些類的equals()方法蠢络,x.equals(y)方法,當(dāng)x和y所引用的對象是同一類對象且屬性內(nèi)容相等時(并不一定是相同對象)脖律,返回true谢肾,否則返回false腕侄。
- 可以根據(jù)用戶需要在自定義類型中重寫equals()方法小泉。
- 注意:當(dāng)此方法被重寫時,通常有必要重寫 hashCode 方法冕杠,以維護 hashCode 方法的常規(guī)協(xié)定微姊,該協(xié)定聲明相等對象必須具有相等的哈希碼。
3.對象轉(zhuǎn)型(casting)
一個基類的引用類型變量可以“指向”其子類的對象分预。(父類引用指向子類對象)——它所看到的只是作為父類的那部分所擁有的那些屬性和方法兢交。
一個基類的引用不可以訪問其子類對象新增加的成員(屬性和方法)。
可以使用 引用變量 instanceof 類名 來判斷該引用型變量所“指向”的對象是否是該類或該類的子類笼痹。
子類的對象可以當(dāng)作基類的對象來使用稱作向上轉(zhuǎn)型配喳,反之稱為向下轉(zhuǎn)型。
對象轉(zhuǎn)型可以增加程序的可擴展性凳干。
4.多態(tài)(動態(tài)綁定晴裹、遲綁定)——核心機制
- 動態(tài)綁定是指在執(zhí)行期間(而非編譯期)判斷所引用對象的實際類型,根據(jù)其實際類型調(diào)用其相應(yīng)的方法救赐。
- 多態(tài)的三個必要條件:
- 要有繼承
- 要有重寫
- 類引用指向子類對象(實際中new的是哪一個子類對象就調(diào)用哪一個子類對象的方法)
- 多態(tài)性通過覆蓋父類的方法來實現(xiàn)涧团,在運行時根據(jù)傳遞對象的引用來調(diào)用相應(yīng)的方法。
- 多態(tài)就是:傳遞子類的引用時,子類有的方法就調(diào)用子類的對象泌绣,子類沒有就調(diào)用父類的對象钮追。
- 多態(tài)機制是面向?qū)ο蟮暮诵臋C制,增強程序的可擴展性阿迈。它是根據(jù)實際的類型去調(diào)用相應(yīng)的方法元媚。
- 繼承是子類使用父類的方法,而多態(tài)則是父類使用子類的方法仿滔。其技術(shù)上的區(qū)別是綁定時期惠毁,晚期綁定一定是多態(tài)。
- 多態(tài)性不僅包括方法多態(tài)性(重載)崎页,還包含一種對象多態(tài)性的概念鞠绰,即子類和父類對象的相互轉(zhuǎn)化關(guān)系。
- 向上轉(zhuǎn)型:父類 父類對象=子類實例 (自動完成)
- 向下轉(zhuǎn)型:子類 子類對象=(子類)父類實例(強制完成)
- 對象多態(tài)性最核心的部分就是方法的重寫與繼承關(guān)系飒焦,只要有繼承關(guān)系蜈膨,只要有重寫過的方法,則子類向父類轉(zhuǎn)型時牺荠,肯定是調(diào)用被子類重寫過的方法(核心)翁巍。
- 多態(tài)性是指在繼承層次或者接口與實現(xiàn)類層次上,如果子類覆蓋了父類的方法休雌,或者說實現(xiàn)類實現(xiàn)了接口 定義的方法灶壶,那么可以通過一般化的用父類或者接口來調(diào)用該方法,JVM在運行期能夠根據(jù)實際傳遞的子 類對象引用杈曲,來調(diào)用相應(yīng)的方法驰凛,產(chǎn)生正確的行為。達(dá)到“同一函數(shù)担扑,不同行為”的效果恰响。java的多態(tài)性是通過動態(tài)綁定實現(xiàn)的。
- 首先是多態(tài)性的前提:
- 在繼承層次或者接口與實現(xiàn)類層次上才有多態(tài)性涌献;
- 子類覆蓋了父類的方法胚宦,或者實現(xiàn)類實現(xiàn)了接口定義的方法,才有多態(tài)性燕垃;
- 其次是多態(tài)性的表現(xiàn):
可以通過一般化的用父類或者接口來調(diào)用某一方法枢劝,JVM在運行期能夠根據(jù)實際傳遞的子類對象引用,來調(diào)用相應(yīng)的方法卜壕,從而產(chǎn)生正確的行為您旁。 - 最后是多態(tài)性的實現(xiàn)原理:
java多態(tài)性是通過函數(shù)的動態(tài)綁定機制實現(xiàn)的
5.抽象類
- 用abstract修飾一個類時,該類是一個抽象類印叁。用abstract修飾一個方法時被冒,該方法是一個抽象方法(相當(dāng)于C++中的純虛函數(shù))军掂。
- 含有抽象方法的類必須為抽象類,抽象類不一定要包含抽象方法昨悼。
- 抽象類必須被繼承蝗锥,抽象方法必須被重寫(由子類去實現(xiàn))。
- 抽象類不能被實例化率触。但是利用多態(tài)可以通過子類實例化终议。
- 抽象方法只需聲明,不需實現(xiàn)葱蝗。
- 抽象類可以包含具體數(shù)據(jù)或具體方法穴张。
- 抽象類能否使用final聲明呢?
a) 抽象類必須被子類繼承
b) 被final聲明的類不能有子類 - 抽象類中能不能存在構(gòu)造方法两曼?
a) 允許有構(gòu)造方法
b) 但是不能直接調(diào)用皂甘,是要交給子類調(diào)用的,子類對象的實例化中永遠(yuǎn)是先調(diào)用父類中的構(gòu)造方法
c) 由此而知悼凑,抽象類只不過是比普通類多了一個抽象方法而已 - 抽象類中的屬性如果要初始化偿枕,則還是要依賴于構(gòu)造方法
- 抽象類實際上可以作為模板存在。
6. final關(guān)鍵字
- final變量(成員變量與局部變量)的值不能被改變户辫。(局部變量作為形參時渐夸,方法內(nèi)部是不允許改變的)
- final的方法不能被重寫。
- final的類不能被繼承渔欢。
7.接口
- 多個無關(guān)的類可以實現(xiàn)一個接口
- 一個類(或者抽象類)可以實現(xiàn)多個無關(guān)的接口墓塌,但是一個接口不能繼承一個抽象類
- 一個接口可以同時繼承多個接口
- 與繼承關(guān)系類似,接口與實現(xiàn)類之間存在多態(tài)性(實現(xiàn)接口的方法就是多態(tài))
- 接口是常量值和抽象方法的定義的集合
- 從本質(zhì)上講奥额,接口是一種特殊的抽象類苫幢,這種抽象類中只包含常量和方法的定義,而沒有變量和方法的實現(xiàn)
- 接口不是類披坏,不能用new運算符實例化一個接口态坦,但是也是可以利用多態(tài)性通過其實現(xiàn)類實例化盐数。
- 雖然不能構(gòu)造接口對象棒拂,卻能聲明接口變量
- 接口變量必須引用實現(xiàn)了接口的類對象
- 可以使用instanceof檢查一個對象是否實現(xiàn)了某個接口
- 接口可以擴展。即可以interface1 extends interface2玫氢。也可以添加新的屬性和方法
- 接口中的方法和域被自動設(shè)置為public static final(C++中多繼承中帚屉,如果它的多個父類之間有相同的成員變量時,運行起來會相當(dāng)?shù)寐闊┭浚⑶視霈F(xiàn)很多問題攻旦。為了修正這個缺陷,java中把成員變量修飾為static使這個變量只屬于這個類(因為在多繼承中生逸,子類對象包含多個父類對象牢屋,而多個父類對象之間是有可能出現(xiàn)相同的成員變量的且预,所以用static修飾,它就不屬于專門的對象)烙无,用final修飾使這個變量不被改變)
- 接口中只能定義抽象方法锋谐,而這些方法默認(rèn)為public的,而且也只能是public的截酷。
- 接口可以多重實現(xiàn)(多繼承)涮拗。
- 多繼承中,子類對象是包含多個父類對象的迂苛。
- 接口實際上是作為標(biāo)準(zhǔn)存在的三热。
8. 接口和抽象類
8.1 適配器設(shè)計模式
a) 正常情況下一個接口的子類要實現(xiàn)全部的抽象方法
b) 但是現(xiàn)在希望可以根據(jù)自己的需求來選擇性的重寫,應(yīng)該怎么是實現(xiàn)呢三幻?
c) 就用一個類先將接口實現(xiàn)了就漾,但是所有的方法都是空實現(xiàn),之后再繼承此類
d) 這個類必須是抽象類念搬,因為抽象類也不能直接使用从藤。此抽象類就相當(dāng)于適配器。
8.2 工廠設(shè)計模式
a) 現(xiàn)在有如下一道程序:
interface Fruit{
public void eat() ;
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃蘋果锁蠕。夷野。。") ;
}
};
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子荣倾。悯搔。。") ;
}
};
class Factory{ // 工廠類
public static Fruit getFruit(String className){
Fruit f = null ;
if("apple".equals(className)){
f = new Apple() ;
}
if("orange".equals(className)){
f = new Orange() ;
}
return f ;
}
};
public class InterDemo{
public static void main(String args[]){
Fruit f = Factory.getFruit(args[0]) ;
if(f!=null){
f.eat() ;
}
}
}
所有的接口的實例化對象都是通過工廠類取得的舌仍,那么客戶端調(diào)用的時候就根據(jù)傳入的名稱不同妒貌,完成的功能也不同。是為了解開接口和子類之間的耦合性铸豁。
8.3 代理設(shè)計模式
interface Give{
public void giveMoney() ;
}
class RealGive implements Give{
public void giveMoney(){
System.out.println("把錢還給我灌曙。。节芥。在刺。。") ;
}
};
class ProxyGive implements Give{ // 代理公司
private Give give = null ;
public ProxyGive(Give give){
this.give = give ;
}
public void before(){
System.out.println("準(zhǔn)備:小刀头镊、繩索蚣驼、鋼筋、鋼據(jù)相艇、手槍颖杏、毒品") ;
}
public void giveMoney(){
this.before() ;
this.give.giveMoney() ; // 代表真正的討債者完成討債的操作
this.after() ;
}
public void after(){
System.out.println("銷毀所有罪證") ;
}
};
public class ProxyDemo{
public static void main(String args[]){
Give give = new ProxyGive(new RealGive()) ;
give.giveMoney() ;
}
};
延伸閱讀
1.JavaSE學(xué)習(xí)筆記系列:面向?qū)ο螅?)
2.JavaSE學(xué)習(xí)筆記系列:面向?qū)ο螅?)