抽象類是一個聲明爲abstract
的類 — 它可能包括也可能不包括抽象方法,抽象類沒法實例化,但能夠進行子類化。html
抽象方法是在沒有實現的狀況下聲明的方法(沒有大括號,後跟分號),以下所示:java
abstract void moveTo(double deltaX, double deltaY);
若是一個類包含抽象方法,那麼該類自己必須被聲明爲abstract
,如:segmentfault
public abstract class GraphicObject { // declare fields // declare nonabstract methods abstract void draw(); }
當抽象類被子類化時,子類一般爲其父類中的全部抽象方法提供實現,可是,若是沒有,那麼子類也必須聲明爲abstract
。api
注意:未聲明爲default
或static
的接口(參見 接口部分)中的方法是隱式抽象的,所以abstract
修飾符不用於接口方法(能夠使用,但不須要)。
抽象類與接口相似,你不能實例化它們,它們可能包含有或沒有實現聲明的方法的組合,可是,使用抽象類,你能夠聲明非靜態和final
的字段,並定義public
、protected
和private
的具體方法。使用接口,全部字段都自動爲public
、static
和final
,而且你聲明或定義的全部方法(做爲默認方法)都是public
,此外,你只能擴展一個類,不管它是不是抽象的,而你能夠實現任意數量的接口。oracle
你應該使用哪一個,抽象類或接口?框架
若是任何這些語句適用於你的狀況,請考慮使用抽象類:spa
protected
和private
)。若是任何這些語句適用於你的狀況,請考慮使用接口:code
JDK中的抽象類的一個示例是AbstractMap,它是集合框架的一部分,它的子類(包括HashMap
、TreeMap
和ConcurrentHashMap
)共享AbstractMap
定義的許多方法(包括get
、put
、isEmpty
、containsKey
和containsValue
)。htm
JDK中實現多個接口的類的一個示例是HashMap,它實現了Serializable
、Cloneable
和Map<K, V>
接口。經過閱讀這個接口列表,你能夠推斷出HashMap
的實例(不管是實現該類的開發人員或公司)能夠克隆,可序列化(這意味着它能夠轉換爲字節流)。請參閱Serializable Objects
部分,並具備map的功能,此外,Map<K, V>
接口已經加強了許多默認方法,例如merge
和forEach
,實現此接口的舊類沒必要定義。對象
請注意,許多軟件庫都使用抽象類和接口,HashMap
類實現了幾個接口,而且還擴展了抽象類AbstractMap
。
在面向對象的繪圖應用程序中,你能夠繪製圓形、矩形、線條、貝塞爾曲線和許多其餘圖形對象,這些對象都具備某些狀態(例如:位置、方向、線條顏色、填充顏色)和行爲(例如:moveTo
、rotate
、resize
、draw
)。全部圖形對象中的一些狀態和行爲都是相同的(例如:位置、填充顏色和moveTo
),其餘須要不一樣的實現(例如,resize
或draw
)。全部GraphicObjects
必須可以本身繪製或調整大小,它們只是作的方式不一樣,這是抽象超類的完美狀況。你能夠利用類似性並聲明全部圖形對象從同一個抽象父對象(例如,GraphicObject
)繼承,以下圖所示。
首先,聲明一個抽象類GraphicObject
,以提供全部子類徹底共享的成員變量和方法,例如當前位置和moveTo
方法,GraphicObject
還聲明瞭方法的抽象方法,例如draw
或resize
,它們須要由全部子類實現,但必須以不一樣的方式實現,GraphicObject
類看起來像這樣:
abstract class GraphicObject { int x, y; ... void moveTo(int newX, int newY) { ... } abstract void draw(); abstract void resize(); }
GraphicObject
的每一個非抽象子類(例如Circle
和Rectangle
)必須提供draw
和resize
方法的實現:
class Circle extends GraphicObject { void draw() { ... } void resize() { ... } } class Rectangle extends GraphicObject { void draw() { ... } void resize() { ... } }
在接口一節中,注意到實現接口的類必須實現全部接口的方法,可是,能夠定義一個不實現全部接口方法的類,前提是該類被聲明爲abstract
,例如:
abstract class X implements Y { // implements all but one method of Y } class XX extends X { // implements the remaining method in Y }
在這種狀況下,類X
必須是abstract
,由於它沒有徹底實現Y
,但實際上,類XX
實現了Y
。
抽象類能夠具備靜態字段和靜態方法,你能夠像使用任何其餘類同樣使用帶有類引用的靜態成員(例如,AbstractClass.staticMethod()
)。