在重溫java基礎的是時候,今天覆習學習了接口與抽象類的區別,稍微整理了一下。
java
問題描述:程序員
在java語言中,接口和抽象類都不能被實例化,都位於繼承樹的頂端,用於被其餘類實現和繼承。接口和抽象類均可以包含抽象方法,實現接口或繼承抽象類的普通子類都必須實現這些抽象方法。ide
在必定程度上,接口和抽象類很類似,在實現某些功能時,二者能夠相互替換,因此有些程序員對接口和抽象類的選擇比較隨意。可是,實際上二者之間的設計理念有很大的不一樣,抽象類用於繼承,表示is-a的關係,而接口用於實現,表示like-a關係,對於它們的選擇甚至反映出對於問題領域本質的理解、對於設計意圖的理解是否正確、合理。那對於接口和抽象類該如何選擇???學習
1、從語義的角度選擇spa
接口與抽象類在語義上區別主要在定義和使用格式上,下面來看抽象類和接口的定義和使用格式:設計
1.抽象類的定義和使用格式對象
在java定義抽象類時,要在關鍵字class前面加上關鍵字abstract。其具體格式以下:繼承
abstract class 類名{接口
類體產品
}
抽象類經過繼承的方式使用,一個子類只能繼承一個抽象類(父類),在子類中必須實現抽象類中全部的抽象方法。具體的實現方式以下:
class 類名 extends 抽象類 {
//實現所有抽象方法
}
2.接口的定義和使用格式
在java中,可使用關鍵字interface定義一個接口,一個接口由變量的定義和方法定義兩部分組成。定義接口的基本語法格式以下:
interface 接口名 {
[public] [static] [final] 變量;
[public] [abstract] 方法;
}
接口經過實現的方式使用,一個類能夠實現多個接口,在實現類中,須要將接口中全部的方法均實現。其具體格式以下:
class 類名 implement 接口列表 {
//實現全部接口中聲明的方法
}
在瞭解接口和抽象類的定義和使用格式後,再來看如何選擇接口或者抽象:
(1)抽象類能夠提供成員的實現細節,而接口不能。設計抽象時,若是要求提供成員的實現細節,可選擇抽象類。
(2)若是設計抽象時選擇抽象類,在之後的版本中能夠隨意爲抽象類添加新成員。而接口在這方面就沒有那麼靈活,只有修改代碼才能添加成員。
(3)一個類能夠實現多個接口,但只能繼承一個抽象類,若是要實現相似於多重繼承的效果,可選擇接口。
2、從設計理念選擇
接口與抽象類在使用方式有着必定的重合,可他們兩者在設計的目的上有着巨大的差異。下面具體分析兩者的差異。
接口做爲系統和外界交互的窗口,接口體現的是一種規範。對於接口的實現者而言,接口規定了實現者必須向外提供哪些服務(以方法的形式來提供);對於接口的調用者而言,接口規定了調用者能夠調用哪些服務,以及如何調用這些服務(就是如何來調用方法)。
從某種角度上來看,接口相似於整個系統的「總綱」,它制定了系統各模塊之間應該遵循的標準,所以一個系統中的接口不該該常常改變。一旦接口改變,對整個系統而言甚至其餘系統的影響將是輻射式的,致使系統中的大部分類都須要重寫。因此,在通常的應用裏,最頂級的是接口,而後是抽象類實現接口,最後纔到具體類實現(例如java的監聽器是一個接口,而適配器就是一個抽象類)。
抽象類則不同,抽象類做爲系統中多個子類的共同父類,它所體現的是模板式設計。抽象類做爲多個子類的的抽象父類,能夠被當成系統實現過程當中的中間產品,這個產品已經實現了系統的部分功能(那些在抽象類中已經提供實現的方法),但這個產品依然不能當成最終產品,必須有更進一步的完善(繼承),這種完善可能有好幾種不一樣的方式。
除此以外,接口和抽象類在用法上也存在一下區別:
l接口裏不能定義靜態方法;抽象類裏能夠定義靜態方法。
l接口裏不包含構造器,抽象類能夠包含構造器。抽象類裏的構造器並非用於建立對象,而是讓其子類調用這些構造器來完成屬於抽象類的初始化操做。
l接口裏不能包含初始化塊,但抽象類能夠包含初始化塊。
l接口裏不包含已經提供實現的方法,只能包含抽象方法,;抽象類則徹底能夠包含普通方法。
l接口裏只能定義靜態常量,不能定義其餘變量。抽象類既能夠定義普通變量,也能夠定義靜態常量。
注意:在接口裏定義的接口、枚舉類、變量默認都採用public static兩個修飾符,無論定義時是否指定這兩個修飾符,系統都會自動使用public static對他們進行修飾,同理,在接口裏,會默認使用public abstract修飾方法。