抽象類

抽象類是使用 abstract 關鍵字標記的類。與非抽象類相反,它可能包含抽象 - 無實現 - 方法。但是,在沒有抽象方法的情況下建立抽象類是有效的。

無法例項化抽象類。只要子類也是抽象的,或者實現超類標記為抽象的所有方法,它就可以是子類(擴充套件)。

抽象類的一個例子:

public abstract class Component {
    private int x, y;
    
    public setPosition(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public abstract void render();
}

當類具有至少一個抽象方法時,必須將其標記為抽象。抽象方法是一種沒有實現的方法。可以在具有實現的抽象類中宣告其他方法,以便為任何子類提供公共程式碼。

嘗試例項化此類將提供編譯錯誤:

//error: Component is abstract; cannot be instantiated   
Component myComponent = new Component();

但是,這個類擴充套件了 Component,併為其所有抽象方法提供了實現,並且可以例項化。

public class Button extends Component {

    @Override
    public void render() {
        //render a button
    }
}

public class TextBox extends Component {

    @Override
    public void render() {
        //render a textbox
    }
}

繼承類的例項也可以轉換為父類(正常繼承),並且在呼叫抽象方法時它們提供多型效果。

Component myButton = new Button();
Component myTextBox = new TextBox();

myButton.render(); //renders a button
myTextBox.render(); //renders a text box

抽象類與介面

抽象類和介面都提供了一種定義方法簽名的方法,同時需要擴充套件/實現類來提供實現。

抽象類和介面之間有兩個主要區別:

  • 類只能擴充套件單個類,但可以實現許多介面。
  • 抽象類可以包含例項(非 static)欄位,但介面可能只包含 static 欄位。

Version < Java SE 8

在介面中宣告的方法不能包含實現,因此在提供稱為抽象方法的實現的其他方法時,使用抽象類。

Version >= Java SE 8

Java 8 允許介面包含預設方法 ,通常使用介面的其他方法實現 ,使得介面和抽象類在這方面同樣強大。

抽象類的匿名子類

為方便起見,java 允許例項化抽象類的子類的匿名例項,這些例項在建立新物件時提供抽象方法的實現。使用上面的示例,這可能如下所示:

Component myAnonymousComponent = new Component() {
    @Override
    public void render() {
        // render a quick 1-time use component
    }
}