抽象類與接口是java語言中對抽象概念進(jìn)行定義的兩種機(jī)制辅愿,正是由于他們的存在才賦予java強(qiáng)大的面向?qū)ο蟮哪芰χ橇痢K麄儍烧咧g對抽象概念的支持有很大的相似,甚至可以互換点待,但是也有區(qū)別阔蛉。
1. 抽象類
如果一個類沒有足夠的信息來描述一個具體的對象,而需要其他具體的類來支撐它癞埠,那么這樣的類我們稱它為抽象類状原。
在解決實際問題時,一般將父類定義為抽象類苗踪,需要使用這個父類進(jìn)行繼承與多態(tài)處理颠区。繼承樹中越是在上方的類越抽象。在多態(tài)機(jī)制中通铲,并不需要將父類初始化對象瓦呼,我們需要的只是子類對象,所以在Java語言中設(shè)置抽象類不可以實例化對象。抽象類就是為了繼承而存在的央串,如果你定義了一個抽象類,卻不去繼承它碗啄,那么等于白白創(chuàng)建了這個抽象類质和,因為你不能用它來做任何事情。
public abstract class Test{
abstract void testAbstract();//定義抽象方法
}
在使用抽象類時需要注意幾點:
- 抽象類不能被實例化稚字,實例化的工作應(yīng)該交由它的子類來完成饲宿,它只需要有一個引用即可。
- 抽象方法必須由子類來進(jìn)行重寫胆描。
- 只要包含一個抽象方法的抽象類瘫想,該方法就必須要定義成抽象類,不管是否還包含有其他方法昌讲。
- 抽象類中可以包含具體的方法国夜,當(dāng)然也可以不包含抽象方法。
- 子類中的抽象方法不能與父類的抽象方法同名短绸。
- abstract不能與final并列修飾同一個類车吹。
- abstract 不能與private、static醋闭、final或native并列修飾同一個方法窄驹。
抽象類和普通類的主要有三點區(qū)別:
- 抽象方法必須為public或者protected(因為如果為private,則不能被子類繼承证逻,子類便無法實現(xiàn)該方法)乐埠,缺省情況下默認(rèn)為public。
- 抽象類不能用來創(chuàng)建對象囚企;
- 如果一個類繼承于一個抽象類丈咐,則子類必須實現(xiàn)父類的抽象方法。如果子類沒有實現(xiàn)父類的抽象方法洞拨,則必須將子類也定義為為abstract類扯罐。
在其他方面,抽象類和普通的類并沒有區(qū)別烦衣。
創(chuàng)建抽象類和抽象方法非常有用,因為他們可以使類的抽象性明確起來,并告訴用戶和編譯器打算怎樣使用他們.抽象類還是有用的重構(gòu)器,因為它們使我們可以很容易地將公共方法沿著繼承層次結(jié)構(gòu)向上移動歹河。
2.接口
接口是抽象類的延伸,可以將它看作是純粹的抽象類花吟。但接口本身就不是類秸歧。
接口,英文稱作interface衅澈,在軟件工程中键菱,接口泛指供別人調(diào)用的方法或者函數(shù)。從這里今布,我們可以體會到Java語言設(shè)計者的初衷,它是對行為的抽象。
一個類可以同時實現(xiàn)多個接口舍咖,不管這些接口之間有沒有關(guān)系烘绽,所以接口彌補(bǔ)了抽象類不能多重繼承的缺陷,但是推薦繼承和接口共同使用,因為這樣既可以保證數(shù)據(jù)安全性又可以實現(xiàn)多重繼承。
public interface test{
void draw();//接口內(nèi)方法,省略abstract關(guān)鍵字
}
- 在接口中定義的方法必須被定義為public或abstract形式算凿,其他修飾權(quán)限不被Java編譯器認(rèn)可,即使不將該方法聲明為public形式犁功,它也是public氓轰。
- 在接口中定義的任何字段都自動是static和final的。
在使用接口過程中需要注意如下幾個問題:
- 一個Interface的方所有法訪問權(quán)限自動被聲明為public浸卦,確切的說只能為public署鸡。
- 接口中可以定義“成員變量”,或者說是不可變的常量镐躲,因為接口中的“成員變量”會自動變?yōu)闉閜ublic static final储玫。可以通過類命名直接訪問:ImplementClass.name萤皂。
- 接口中不存在實現(xiàn)的方法撒穷。
- 實現(xiàn)接口的非抽象類必須要實現(xiàn)該接口的所有方法。抽象類可以不用實現(xiàn)裆熙。
- 不能使用new操作符實例化一個接口端礼,但可以聲明一個接口變量,該變量必須引用(refer to)一個實現(xiàn)該接口的類的對象入录「虬拢可以使用 instanceof 檢查一個對象是否實現(xiàn)了某個特定的接口。例如:if(anObject instanceof Comparable){}僚稿。
- 在實現(xiàn)多接口的時候一定要避免方法名的重復(fù)凡桥。
3. 抽象類與接口的異同
3.1 相同點
- 都不能被實例化
- 接口的實現(xiàn)類或者抽象類的子類都只有實現(xiàn)了接口或者抽象類中的方法后才能被實例化。
3.2 不同點
- 接口只有定義蚀同,不能有方法的實現(xiàn)缅刽;
抽象類可以有定義與實現(xiàn),即其方法可以在抽象類中被實現(xiàn)蠢络。
- 實現(xiàn)接口的關(guān)鍵字為implements衰猛;
繼承抽象類的關(guān)鍵字為extends。
一個類可以實現(xiàn)多個接口刹孔,但一個類只能繼承一個抽象類啡省。使用接口可以間接的達(dá)到多重繼承的目的。
- 接口強(qiáng)調(diào)特定功能的實現(xiàn),其設(shè)計理念為“l(fā)ike-a”關(guān)系卦睹;
抽象類強(qiáng)調(diào)所屬關(guān)系畦戒,其設(shè)計理念是“is-a”關(guān)系。
- 接口中定義的成員變量默認(rèn)為public分预、static兢交、final,只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員笼痹,而且必須為其賦初值;其所有的方法都是public酪穿、abstract的且只能被這兩個關(guān)鍵字修飾
抽象類中的成員變量默認(rèn)為default凳干,當(dāng)然也可以被定義為private、protected和public被济,這些成員變量可以在子類中被重新定義救赐,也可以被重新賦值,抽象類中的抽象方法(其前有abstract修飾)不能用private只磷、static经磅、synchronized和native等訪問修飾符修飾,同時方法必須以分號為結(jié)尾钮追,并且不帶花括號{}预厌。
當(dāng)功能需要累計時,使用抽象類元媚,不需要積累時轧叽,使用接口。
- 接口被運用于實現(xiàn)比較常用的功能刊棕,便于日后維護(hù)或者添加刪除方法炭晒;
抽象類更傾向于充當(dāng)公共類的角色,不適合于日后重新對里面的代碼進(jìn)行修改甥角。
參考并感謝
1. java提高篇(四)-----抽象類與接口
2. 深入理解Java的接口和抽象類
3. Java程序員面試筆試真題與解析