您好,登錄后才能下訂單哦!
這篇文章主要講解了“java抽象類和接口的區(qū)別有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java抽象類和接口的區(qū)別有哪些”吧!
部分來自:Java抽象類與接口的區(qū)別-ImportNew
抽象類 —— 一種模板式設(shè)計
abstract void fun();
[public] abstract class ClassName { abstract void fun(); }
抽象類就是為了繼承而存在
抽象類不能被實(shí)例化,實(shí)例化 交由它的子類完成,它只需要有一個引用即可。
抽象方法由子類來進(jìn)行重寫。必須為public或者protected,缺省情況下默認(rèn)為public
只要包含一個抽象方法的抽象類,該方法必須要定義成抽象類,不管是否還包含有其他方法。
抽象類中可以包含具體的方法,當(dāng)然也可以不包含抽象方法。
abstract不能與final并列修飾同一個類。
abstract 不能與private、static、final或native并列修飾同一個方法。
抽象類的意義在于:
為其子類提供一個公共的父類型,避免該類被實(shí)例化;
封裝子類中的重復(fù)內(nèi)容(成員變量和方法);
定義公共抽象方法,由子類提供不同的實(shí)現(xiàn)。
[public] interface InterfaceName { }
接口 本身也是類
變量 被隱式地指定為 public static final (只能是 public static final 變量,用 private 或 private 修飾會報編譯錯誤)
方法【必須都抽象方法】 被隱式地指定為public abstract (只能是 public abstract 方法)
接口中所有的方法不能有具體的實(shí)現(xiàn)(jdk1.8中可以有default方法和static方法)
接口是一種極度抽象的類型,比抽象類更加“抽象”,并且一般情況下不在接口中定義變量(如果定義只能是Static Final)
語法層面上的區(qū)別
1)抽象類可以提供成員方法的實(shí)現(xiàn)細(xì)節(jié),而接口中只能存在public abstract 方法;
2)抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;
3)接口中不能含有靜態(tài)代碼塊以及靜態(tài)方法,而抽象類可以有靜態(tài)代碼塊和靜態(tài)方法;
4)一個類只能繼承一個抽象類,而一個類卻可以實(shí)現(xiàn)多個接口。
設(shè)計層面上的區(qū)別
什么是模板式設(shè)計?例子:用模板A設(shè)計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A,如果公共部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和ppt C進(jìn)行改動
什么是輻射式設(shè)計?比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新。
抽象類是自底向上抽象而來的,接口是自頂向下設(shè)計出來的
對于抽象類,如果需要添加新的方法,可以直接在抽象類中添加具體的實(shí)現(xiàn),子類可以不進(jìn)行變更;
而對于接口則不行,如果接口進(jìn)行了變更,則所有實(shí)現(xiàn)這個接口的類都必須進(jìn)行相應(yīng)的改動。
抽象類和接口的對比
參數(shù) | 抽象類 | 接口 |
默認(rèn)的方法實(shí)現(xiàn) | 它可以有默認(rèn)的方法實(shí)現(xiàn) | 接口完全是抽象的。它根本不存在方法的實(shí)現(xiàn) |
實(shí)現(xiàn) | 子類使用extends關(guān)鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有聲明的方法的實(shí)現(xiàn)。 | 子類使用關(guān)鍵字implements來實(shí)現(xiàn)接口。它需要提供接口中所有聲明的方法的實(shí)現(xiàn) |
構(gòu)造器 | 抽象類可以有構(gòu)造器 | 接口不能有構(gòu)造器 |
與正常Java類的區(qū)別 | 除了你不能實(shí)例化抽象類之外,它和普通Java類沒有任何區(qū)別 | 接口是完全不同的類型 |
訪問修飾符 | 抽象方法可以有public、protected和default這些修飾符 | 接口方法默認(rèn)修飾符是public。你不可以使用其它修飾符。 |
main方法 | 抽象方法可以有 main 方法并且我們可以運(yùn)行它 | 接口沒有main方法,因此我們不能運(yùn)行它。 |
多繼承 | 抽象方法可以繼承一個類和實(shí)現(xiàn)多個接口 | 接口只可以繼承一個或多個其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有點(diǎn)慢的,因?yàn)樗枰獣r間去尋找在類中實(shí)現(xiàn)的方法。 |
添加新方法 | 如果你往抽象類中添加新的方法,你可以提供默認(rèn)的實(shí)現(xiàn)。因此你不需要改變你現(xiàn)在的代碼。 | 如果你往接口中添加方法,那么你必須改變實(shí)現(xiàn)該接口的類。 |
如果你擁有一些方法并且想讓它們中的一些有默認(rèn)實(shí)現(xiàn),那么使用抽象類吧。
如果你想實(shí)現(xiàn)多重繼承,那么你必須使用接口。由于Java不支持多繼承,子類不能夠繼承多個類,但可以實(shí)現(xiàn)多個接口。因此你就可以使用接口來解決它。
如果基本功能在不斷改變,那么就需要使用抽象類。如果不斷改變基本功能并且使用接口,那么就需要改變所有實(shí)現(xiàn)了該接口的類。
門和警報的例子:門都有open( )和close( )兩個動作,此時我們可以定義通過抽象類和接口來定義這個抽象概念:
abstract class Door { public abstract void open(); public abstract void close(); }
或者:
interface Door { public abstract void open(); public abstract void close(); }
這種方法違反了面向?qū)ο笤O(shè)計中的一個核心原則ISP (Interface Segregation Principle)【見批注】,在Door的定義中把Door概念本身固有的行為方法和另外一個概念"報警器"的行為方 法混在了一起。這樣引起的一個問題是那些僅僅依賴于Door這個概念的模塊會因?yàn)?quot;報警器"這個概念的改變而改變,反之依然。
Door的open() 、close()和alarm()根本就屬于兩個不同范疇內(nèi)的行為,open()和close()屬于門本身固有的行為特性,而alarm()屬于延伸的附加行為。因此最好的解決辦法是單獨(dú)將報警設(shè)計為一個接口,包含alarm()行為,Door設(shè)計為單獨(dú)的一個抽象類,包含open和close兩種行為。再設(shè)計一個報警門繼承Door類和實(shí)現(xiàn)Alarm接口。
interface Alram { void alarm(); } abstract class Door { void open(); void close(); } class AlarmDoor extends Door implements Alarm { void oepn(){ //.... } void close(){ //.... } void alarm(){ //.... } }
批注:
ISP(Interface Segregation Principle接口分離原則):面向?qū)ο蟮囊粋€核心原則。它表明使用多個專門的接口比使用單一的總接口要好。
一個類對另外一個類的依賴性應(yīng)當(dāng)是建立在最小的接口上的。
一個接口代表一個角色,不應(yīng)當(dāng)將不同的角色都交給一個接口。沒有關(guān)系的接口合并在一起,形成一個臃腫的大接口,這是對角色和接口的污染。
感謝各位的閱讀,以上就是“java抽象類和接口的區(qū)別有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java抽象類和接口的區(qū)別有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。