Java™ 教程(抽象方法和類)

抽象方法和類

抽象類是一個聲明爲abstract的類 — 它可能包括也可能不包括抽象方法,抽象類沒法實例化,但能夠進行子類化。html

抽象方法是在沒有實現的狀況下聲明的方法(沒有大括號,後跟分號),以下所示:java

abstract void moveTo(double deltaX, double deltaY);

若是一個類包含抽象方法,那麼該類自己必須被聲明爲abstract,如:segmentfault

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}

當抽象類被子類化時,子類一般爲其父類中的全部抽象方法提供實現,可是,若是沒有,那麼子類也必須聲明爲abstractapi

注意:未聲明爲 defaultstatic的接口(參見 接口部分)中的方法是隱式抽象的,所以 abstract修飾符不用於接口方法(能夠使用,但不須要)。

抽象類與接口相比

抽象類與接口相似,你不能實例化它們,它們可能包含有或沒有實現聲明的方法的組合,可是,使用抽象類,你能夠聲明非靜態和final的字段,並定義publicprotectedprivate的具體方法。使用接口,全部字段都自動爲publicstaticfinal,而且你聲明或定義的全部方法(做爲默認方法)都是public,此外,你只能擴展一個類,不管它是不是抽象的,而你能夠實現任意數量的接口。oracle

你應該使用哪一個,抽象類或接口?框架

  • 若是任何這些語句適用於你的狀況,請考慮使用抽象類:spa

    • 你但願在幾個密切相關的類之間共享代碼。
    • 你但願擴展抽象類的類具備許多公共方法或字段,或者須要非公共的訪問修飾符(如protectedprivate)。
    • 你想聲明非靜態或非最終字段,這使你可以定義可以訪問和修改它們所屬的對象的狀態的方法。
  • 若是任何這些語句適用於你的狀況,請考慮使用接口:code

    • 你但願不相關的類將實現你的接口,例如,ComparableCloneable接口由許多不相關的類實現。
    • 你但願指定特定數據類型的行爲,但不關心誰實現其行爲。
    • 你但願利用類型的多重繼承。

JDK中的抽象類的一個示例是AbstractMap,它是集合框架的一部分,它的子類(包括HashMapTreeMapConcurrentHashMap)共享AbstractMap定義的許多方法(包括getputisEmptycontainsKeycontainsValue)。htm

JDK中實現多個接口的類的一個示例是HashMap,它實現了SerializableCloneableMap<K, V>接口。經過閱讀這個接口列表,你能夠推斷出HashMap的實例(不管是實現該類的開發人員或公司)能夠克隆,可序列化(這意味着它能夠轉換爲字節流)。請參閱Serializable Objects部分,並具備map的功能,此外,Map<K, V>接口已經加強了許多默認方法,例如mergeforEach,實現此接口的舊類沒必要定義。對象

請注意,許多軟件庫都使用抽象類和接口,HashMap類實現了幾個接口,而且還擴展了抽象類AbstractMap

抽象類示例

在面向對象的繪圖應用程序中,你能夠繪製圓形、矩形、線條、貝塞爾曲線和許多其餘圖形對象,這些對象都具備某些狀態(例如:位置、方向、線條顏色、填充顏色)和行爲(例如:moveTorotateresizedraw)。全部圖形對象中的一些狀態和行爲都是相同的(例如:位置、填充顏色和moveTo),其餘須要不一樣的實現(例如,resizedraw)。全部GraphicObjects必須可以本身繪製或調整大小,它們只是作的方式不一樣,這是抽象超類的完美狀況。你能夠利用類似性並聲明全部圖形對象從同一個抽象父對象(例如,GraphicObject)繼承,以下圖所示。

classes-graphicObject.gif

首先,聲明一個抽象類GraphicObject,以提供全部子類徹底共享的成員變量和方法,例如當前位置和moveTo方法,GraphicObject還聲明瞭方法的抽象方法,例如drawresize,它們須要由全部子類實現,但必須以不一樣的方式實現,GraphicObject類看起來像這樣:

abstract class GraphicObject {
    int x, y;
    ...
    void moveTo(int newX, int newY) {
        ...
    }
    abstract void draw();
    abstract void resize();
}

GraphicObject的每一個非抽象子類(例如CircleRectangle)必須提供drawresize方法的實現:

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())。


上一篇:Object做爲超類

下一篇:數字

相關文章
相關標籤/搜索