抽象類
抽象方法
當(dāng)多個類中具有共性方法時龄坪,我們就會向上抽取形成父類赊抖,并在父類中定義這個共性方法挽荡。
而有時按脚,父類中的方法并不能明確每個子類的具體實現(xiàn)醋虏,那么這種方法就稱為抽象方法席吴。
抽象方法的定義:用abstract關(guān)鍵字修飾溅漾,且沒有方法體扩淀,直接以分號結(jié)尾的方法。
抽象方法必須被子類實現(xiàn)蔫敲。
抽象類
具有抽象方法的類就是抽象類,抽象類中才可以寫抽象方法饲嗽。
抽象類的特點
抽象類必須被abstract修飾
不能被創(chuàng)建對象,(不能實例化奈嘿,不能new)
抽象方法必須被abstract修飾貌虾,且沒有方法體,直接以分號結(jié)尾的方法裙犹。
抽象類中可以沒有抽象方法(但一般不那么做尽狠,因為這么做沒有任何意義)。抽象方法必須在抽象類中叶圃。(抽象類中才可以定義抽象方法袄膏,如果你寫了抽象方法,那一定要把類變成抽象類掺冠。)
抽象類中可以有普通方法而且非常有必要哩陕,它是可以給子類繼承的,為那些具有相同功能相同實現(xiàn)細(xì)節(jié)的類赫舒。(抽象類中可以有普通方法悍及,但是你不能實例化這個抽象類也就不能調(diào)用這個普通方法,還定義普通方法干什么呢接癌?答:雖然它本身不能不能調(diào)用普通方法心赶,但是它的子類可以繼承普通方法,可以實例化調(diào)用缺猛,當(dāng)一些子類中都具有和其他子類相同的功能并且實現(xiàn)方式也一樣時缨叫,就可以把方法定義成普通方法,防止重復(fù)定義荔燎。定義抽象方法是因為具有這個功能但具體實現(xiàn)方式不同所以耻姥,定義普通方法是因為具有同樣的功能并且細(xì)節(jié)實現(xiàn)也是一樣。每個類中單獨定義自己的方法是因為跟其他子類沒有共同點有咨,這個這個小類獨有的功能琐簇。 總之同功能不同實現(xiàn),抽象座享。同功能同實現(xiàn)普通)
抽象類的使用
步驟:
1婉商、定義抽象類的子類
2、重寫抽象類的所有抽象方法
3渣叛、創(chuàng)建子類對象丈秩,調(diào)用重寫后的方法
細(xì)節(jié)
問:反正子類都要重新定義自己的功能,為什么還要繼承具有抽象方法的抽象類?
答:因為繼承了抽象類后就必須重寫所有的抽象方法淳衙,這表示當(dāng)前的子類是屬于父類繼承體系的一份子蘑秽,作為該類的子類就必須具備此功能饺著。
問:抽象類中不定義抽象方法的意義是什么?
答:一個類使用abstract修飾后肠牲,它就不能被實例化了幼衰,就必須通過子類的繼承和重寫才有意義。這是設(shè)計模式的體現(xiàn)埂材。
問:抽象類一定是父類嗎塑顺?
答:從代碼角度來說不一定汤求;從實際意義和思考角度來說俏险,抽象類一定是一個父類。
抽象可以再抽象
比如A抽象類扬绪,B繼承A竖独。B本來是必須實現(xiàn)A中的方法的,但是B不想實現(xiàn)A中的方法挤牛,它還想再添加兩個抽象方法或者不添加莹痢,讓其他人去實現(xiàn)這個B那么可以給B加abstract。
使用匿名內(nèi)部類的方法
創(chuàng)建抽象類的子類對象墓赴,重寫方法后竞膳,就可以直接調(diào)用方法
格式:
new 抽象類名 / 接口名(){ // 重寫所有抽象方法 };還可以在分號前調(diào)用方法
這個有點像JavaScript中的var x= function(){
//函數(shù)體
};的方式
匿名對象的創(chuàng)建
概念:創(chuàng)建對象時,不指定變量名
好處:簡化代碼的書寫
弊端:匿名對象只能使用一次
-
格式:
new 數(shù)據(jù)類型(參數(shù));
接口
接口的好處
實現(xiàn)額外功能的擴(kuò)展
接口是對外暴露的規(guī)則诫硕,表示如果想要使用接口來擴(kuò)展功能坦辟,那么必須符合這些規(guī)則,并且是作為同一體系下的內(nèi)容
達(dá)到功能與具體實現(xiàn)的相分離(解耦)
一個接口就代表一個功能章办,它是功能的抽取锉走,模塊的抽取
問:接口是什么呢?
答:接口是一個比抽象類更加抽象的“抽象類”藕届,它是功能的集合挪蹭。
它使用interface關(guān)鍵字代替了class。
注:接口的源文件還是.java文件休偶,并且編譯后的文件還是.class文件梁厉,所以說接口是一個特殊的類
接口中成員的特點
成員變量
接口中的成員變量默認(rèn)被public static final所修飾,相當(dāng)于共同使用的公共工具可以用但不能修改踏兜,別人還要用呢懂算,public是為了可以跨包的訪問反正你也不能修改我是安全的,我可以隨便公開庇麦。成員方法
接口中的成員方法默認(rèn)被public abstract修飾计技,默認(rèn)的就已經(jīng)加上了,你加上修飾也是加山橄,不加就是默認(rèn)垮媒,已修改就錯。接口的使用
1、自定義類實現(xiàn)(繼承)接口睡雇,使用關(guān)鍵字implements
2萌衬、重寫所有抽象方法
3、創(chuàng)建子類(實現(xiàn)類)對象它抱,調(diào)用重寫后的方法接口的不同使用方式
1秕豫、類實現(xiàn)接口
一個類為了擴(kuò)展額外的功能,而去實現(xiàn)接口观蓄,那么這個了類需要重寫接口中的方法
2混移、類在繼承類的時候?qū)崿F(xiàn)接口
一個類是屬于某一個繼承體系的,它是某一個類的一份子侮穿,所以繼承它之后具備了該類的所有屬性和功能歌径;同時還實現(xiàn)了功能的擴(kuò)展。
3亲茅、類的多實現(xiàn)
一個類實現(xiàn)了多個接口后回铛,需要從寫這些接口的所有抽象方法,來實現(xiàn)功能的擴(kuò)展克锣。
接口繼承接口茵肃,接口可以繼承多個接口
接口和抽象類的異同
同
都不能創(chuàng)建對象
都需要子類(實現(xiàn)類)重寫方法后才有意義
都是向上抽取得到的
都具有抽象方法
異
抽象類中可以有非抽象方法
接口使用的是interface和實現(xiàn)implements、抽象類使用的是class和繼承extends
接口可以多繼承袭祟,抽象類只能單繼承验残。
繼承類表示的是屬于這個繼承體系中的一份子,具有該類的共性內(nèi)容榕酒;實現(xiàn)接口表示的是功能的擴(kuò)展胚膊。體系模塊一脈相承任何子孫都要有和功能模塊不同子孫不同的功能。
問:接口和抽象類用哪個呢想鹰?
答:推薦使用接口紊婉,避免了單繼承的局限性;當(dāng)子類有共性方法辑舷,且這些方法的具體實現(xiàn)也相同時喻犁。
Java 1.8的新特性
在接口中也可以定義非抽象方法啦!:位骸肢础!
格式:
default 返回類型 方法名(){
}
總結(jié)
接口中沒有普通方法,只有抽象方法碌廓。接口中的所有成員都是默認(rèn) 公開 靜態(tài) 最終传轰。但是目前Java1.8新增了default修飾的方法,就是普通方法谷婆,這個普通方法就是個普通方法慨蛙,和抽象類中的普通方法類似辽聊。
抽象類可以重寫普通方法,可以繼承普通方法期贫。但是無論是對于抽象方法還是普通方法跟匆,無論是繼承還是接口實現(xiàn)都要遵守子類中的方法作用權(quán)限要大于等于父類。
接口可以繼承接口可以多繼承接口通砍,但是接口不能實現(xiàn)接口玛臂。即接口不能impelements接口。
接口不可以循環(huán)閉環(huán)繼承封孙。
接口中default的普通方法依然是public類型迹冤。這個default在接口中是指普通方法的關(guān)鍵字不是指訪問權(quán)限。
抽象類的子類和子類對象可以更改和調(diào)用抽象類中的變量敛瓷。
接口是抽象中的抽象叁巨,終極抽象斑匪。抽象類中還存在相同實現(xiàn)的方法呐籽,而在接口中還會再向上抽象直到不存在相同的實現(xiàn)方法只存在相同的功能。但是這個設(shè)定再1.8被打破存在default蚀瘸。
例如:
狗和貓可以抽象為動物狡蝶,雖然吃的不一樣可以定義為抽象方法,但睡覺一樣可以定義為具體方法贮勃。再把動物和人類進(jìn)行抽象贪惹,這時候不但連吃不一樣,連睡覺都不一樣寂嘉,這時候接口叫生物奏瞬,吃和睡都是抽象方法。所以生物是抽象類∪ⅲ現(xiàn)在抽象類中可以有具體方法并且可以多繼承多實現(xiàn)硼端,漸漸的抽象類沒有了市場。
額外
一個.java文件中可以寫兩個類寓搬,但是編譯的時候還是會把文件中的每一個類單獨編譯成一個.class文件中珍昨,一個類一個.class。一個接口也會獨占一個.class文件句喷。
抽象方法必須被實現(xiàn)镣典,具體方法會自動被繼承。
- 靜態(tài)變量是在類加載的收就加載了唾琼,它是類級別的兄春,所以是所有對象的共享數(shù)據(jù)。
- 在一個類中可以出現(xiàn)重載锡溯,但是重載只關(guān)乎參數(shù)名和參數(shù)列表和返回類型無任何關(guān)系赶舆,所以以返回類型來作為重載的是錯誤肴裙。即,方法名相同涌乳,參數(shù)列表相同蜻懦,但返回類型不同的方法直接報錯。所以當(dāng)一個類要實現(xiàn)兩個接口時這兩個接口有的方法名相同但參數(shù)列表不同可以作為重載夕晓,但是只是返回類型不同會報錯崩潰宛乃。因此接口的實現(xiàn)以及多接口的實現(xiàn)可以接受重載和重載的規(guī)則一樣,但不接受無理取鬧蒸辆。僅是返回類型不同絕對不允征炼。