Java abstract

Javaのabstractは抽象クラスを作るためのアクセス修飾子です。抽象クラスとはインスタンス化できないクラスのことで、継承させて使うためのクラスです。この記事では、abstractと抽象クラスの使い方をご紹介します。

宣言できるもの

abstractで宣言できるものとして、クラスとメソッドがあります。

抽象クラス

abstract修飾子を付けたクラスの定義は、抽象クラスの定義になる。抽象クラスとは、直接インスタンス化できないクラスである。通常、抽象クラスから派生クラスを作成して使用する。 抽象クラスは class の前に abstract を付けます。 抽象クラスではメソッドを宣言することができます。これを仮想関数と呼びます。 基底クラスに仮想関数がある場合、仮想関数を実装しなければ、その派生クラスも抽象クラスになります。

abstract class AbstractClassExample {
  public abstract void display();
}

メソッド

abstract修飾子を付けたメソッドの宣言は、抽象メソッドの宣言となる。

abstract class AbstractClassExample {
  public abstract void display();
}

抽象メソッドとは、サブクラスで必ずオーバーライドされるメソッドである。

class Example extends AbstractClassExample {
  public void display() {
    System.out.println("Example::display");
  }
  public static void main(String arg[]) {
    Example example = new Example();
    example.display();
  }
}

コンストラクタ

抽象クラスを直接インスタンス化することはできないが、コンストラクタを定義することはできる。

abstract class Foo {
  int bar;
  public Foo(int bar) {
    this.bar = bar;
  }
  abstract public void baz();
}

static

メソッドにabstract修飾子とstatic修飾子の両方を指定することはできない。

public abstract class AbstractClassExample {
  public final abstract void display();
}

AbstractClassExample.java:2: error: illegal combination of modifiers: abstract and final public final abstract void display();
^
1 error

interfaceとの違い

抽象クラスと似たものに インタフェース がある。抽象クラスとインタフェースの違いを次に示す。

抽象クラス インタフェース
インスタンス化できるか No No
継承するときのキーワード extends implements
サブクラスが多重継承できるか No Yes
抽象メソッドを宣言できるか Yes Yes
具象メソッドを定義できるか Yes Yes
final変数を定義できるか Yes Yes
非final変数を定義できるか No Yes

インタフェースで変数を定義することはできるが、暗黙的に修飾子が public static final となる制限がある。

final

抽象クラスに final 修飾子を付けることはできない。抽象クラスはサブクラスによって継承されることを前提としているが、final 修飾子はそれを禁止するため、矛盾するからである。

Template Methodパターン

デザインパターンのひとつである「Template Methodパターン」は、抽象クラスを利用して大まかな処理をメソッドで定義し、詳細な処理は抽象メソッドにして継承クラスで定義させる。

public abstract class TemplateMethod {
  public abstract boolean foo();
  public abstract void bar();
  public abstract void baz();
  public void example() {
    if (foo()) {
      bar();
    } else {
      baz();
    }
  }
}
class A extends TemplateMethod {
  public boolean foo() {
    // do something
  }
  public void bar() {
    // do something
  }
  public void baz() {
    // do something
  }
}
class B extends TemplateMethod {
  public boolean foo() {
    // do something
  }
  public void bar() {
    // do something
  }
  public void baz() {
    // do something
  }
}

参考文献

Oracle (2021) "Abstract Methods and Classes" The Java™ Tutorials