Javaプログラミングにおける、インタフェースと抽象クラスと具象クラスの違い

Javaプログラミングにおける、

  • インタフェース
  • 抽象クラス
  • 具象クラス

これらの違いには、何がありますか?

「メソッドの宣言」と「メソッドの実装」において、それぞれの違いがあります。
例えば、「メソッドの宣言」または「メソッドの実装」において、個数に違いがあります。

「メソッドの宣言」と「メソッドの実装」の違いにより、
例えば具象クラスは「メソッドの実装」だけがあるので、クラス的に見ると「完成された物という感じ」がします。

Javaプログラミングにおける、インタフェースと抽象クラスと具象クラス、それぞれの違い

Javaプログラミングにおける、

  • インタフェース
  • 抽象クラス
  • 具象クラス

これらについて、

  • 「メソッド宣言」の部分
  • 「メソッド実装」の部分

この部分に「記号付き名称」を付けて、違いを比較してみます。

「メソッドの宣言」を(▲メソッドの宣言)、
「メソッドの実装」を(●メソッドの実装)にします。

インタフェースと抽象クラスと具象クラス、それらの違いを理解するのに役立てば幸いです。

インタフェースOpenの例

以下、インタフェースの例を書きます。
プログラムの詳細を理解する必要は、ありません。

public interface Open{

    //▲メソッドの宣言
    public void open();
}

抽象クラスAbstractOpenActionの例

以下、抽象クラスの例を書きます。
プログラムの詳細を理解する必要は、ありません。

public abstract class AbstractOpenAction extends Action {

    //▲メソッドの宣言
    public abstract ActionForward open(ActionMapping mapping, OpenForm form,
    HttpServletRequest request, HttpServletResponse response);

    //●メソッドの実装
    public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) {

        OpenForm openForm = (OpenForm)form;
        String action = openForm.getAction();

        中略

    }

    中略

}

具象クラスOpenActionの例

以下、具象クラスの例を書きます。
プログラムの詳細を理解する必要は、ありません。

public class OpenAction extends AbstractOpenAction {

    //●メソッドの実装
    public ActionForward open(ActionMapping mapping, OpenForm form,
    HttpServletRequest request, HttpServletResponse response) {

        ServletContext context = super.getServlet().getServletContext();
        XmlTimesheetManager timesheetManager = 
            (XmlTimesheetManager)context.getAttribute("timesheetManager");

        中略

    }

インタフェースと抽象クラスと具象クラス、それらの違いの比較

Javaプログラミングにおける、

  • インタフェースOpen
  • 抽象クラスAbstractOpenAction
  • 具象クラスOpenAction

これらについて、上記の「記号付き名称」を使って比較すると、次のようになります。

インタフェース Open抽象クラス AbstractOpenAction具象クラス OpenAction
▲メソッドの宣言
open()
▲メソッドの宣言
open()
 ●メソッドの実装
open()
  ●メソッドの実装
execute()
 
インタフェースと抽象クラスと具象クラス、それらの違いの比較

インタフェースOpenは、(▲メソッドの宣言)だけがあります。

抽象クラスAbstractOpenActionは、(▲メソッドの宣言)と(●メソッドの実装)があります。

具象クラスOpenActionは、(●メソッドの実装)だけがあります。

(▲メソッドの宣言)と(●メソッドの実装)の存在を比べることで、

  • インタフェース
  • 抽象クラス
  • 具象クラス

これらの違いについて、何となく理解できたら良いと思います。

インタフェースには「メソッドの宣言」だけあって、「メソッドの実装」はないです。

クラス的に見ると、「空っぽという感じ」がします。

抽象クラスについては、インタフェースと具象クラスの「中間に存在するクラスという感じ」がします。

具象クラスは、「メソッドの実装」だけが存在しています。

クラス的に見ると、「完成された物という感じ」がします。

※ここまでの記事は、2004年10月当時の記事になります。

Javaプログラミング
Javaプログラミング・イメージ画像

オブジェクト指向にとって重要、インタフェースと抽象クラスと具象クラス

  • インタフェース
  • 抽象クラス
  • 具象クラス

これらは、Javaプログラミングにおいて、オブジェクト指向の概念を実現する際、重要な要素です。

インタフェースは、あるクラスが持つべきメソッドの宣言を集めたものです。

そのクラスが、どのような機能を提供するかを定義します。

抽象クラスは、インタフェースと同じくメソッドの宣言を持つことができます。

なお、一部のメソッドには、実装(処理内容)を持つことができます。

具象クラスは、全てのメソッドが実装されているクラスです。

具象クラスは、インタフェースや抽象クラスを実装(implements)、または継承(extends)します。
その結果により持つことになった全てのメソッドに対して、実装を与えたクラスです。

具象クラスは、インスタンス化できます。new演算子で、オブジェクトを生成できます。

インタフェースや抽象クラスは、インスタンス化できません。

インタフェースと抽象クラスと具象クラスのソースコードの例

動物、犬、柴犬、これらを題材にして、
インタフェースと抽象クラスと具象クラスのソースコードを、以下に示します。

// インタフェース
interface Animal {
  // メソッドの宣言
  void bark();
}

// 抽象クラス
abstract class Dog implements Animal {
  // メソッドの実装
  public void bark() {
    System.out.println("ワンワン");
  }
}

// 具象クラス
class Shiba extends Dog {
  // メソッドの実装
  public void wagTail() {
    System.out.println("巻き尾のしっぽを振る");
  }
}

// テスト用のメインメソッド
public class Test {
  public static void main(String[] args) {

    // 具象クラスのインスタンス化
    Shiba shiba = new Shiba();

    // メソッドの呼び出し
    shiba.bark(); // ワンワン
    shiba.wagTail(); // 巻き尾のしっぽを振る
  }
}

上記のソースコードにおいて、
インタフェースと抽象クラスと具象クラスの働きにおいて、違いが見られます。

例えば「鳴く」というメソッドを適用させる、Animalインタフェース

インタフェースは、ある種類のオブジェクトが共通に持つべき「契約」や「規約」です。

動物というインタフェースを定義すると、そのインタフェースには、例えば「鳴く」というメソッドを用意できます。

この場合、動物というインタフェースを実装したクラスは、「鳴く」というメソッドを必ず持つ必要があります。

例えば「鳴く」というメソッドの実装を用意できる、Dog抽象クラス

抽象クラスは、ある種類のオブジェクトが共通に持つ「特徴」や「性質」です。

犬という抽象クラスを定義すると、その抽象クラスには、例えば「鳴く」というメソッドの実装を用意することになります。

この場合、犬という抽象クラスを継承したクラスは、「鳴く」というメソッドをそのまま使うことができます。

例えば「鳴く」と「巻き尾のしっぽを振る」というメソッドを利用できる、Shiba具象クラス

具象クラスは、ある種類のオブジェクトが持つ「個性」や「特徴」です。

例えば、柴犬という具象クラスを定義すると、その具象クラスには「鳴く」というメソッドの実装だけでなく、「巻き尾のしっぽを振る」というメソッドを用意できます。

柴犬という具象クラスのインスタンスは、「鳴く」と「巻き尾のしっぽを振る」という機能を使うことができます。

インターフェースと抽象クラスと具象クラスの違い

Javaプログラミングにおける、インターフェースと抽象クラスと具象クラスの違いについては、以下のようにまとめられます。

  • インタフェースは、一般的に実装がない。
    Java 8以降、デフォルトメソッドを定義できます。
  • 抽象クラスは、一部の実装がある。
  • 具象クラスは全ての実装があり、インスタンス化できる。

実装のない型、インタフェース

インタフェースとは、メソッドのシグネチャや定数の宣言だけを持つ、実装のない型です。

インタフェースは、複数のクラスに共通の振る舞いを定義するために使われます。

インタフェースを実装するクラスは、インタフェースで宣言された全てのメソッドをオーバーライドしなければなりません。

インタフェースは多重継承をサポートしており、一つのクラスは複数のインタフェースを実装できます。

メソッドの実装を持つ、Javaのインタフェース

Java 8以降、インタフェースには以下のメソッドを定義できます。

  • デフォルトメソッド
  • 静的メソッド

これらのメソッドは、インタフェースに対して実装を提供できます。

インタフェースに対して実装を提供するソースコードを、以下に示します。

interface Animal {

  //デフォルトメソッド
  default void sound() {
    System.out.println("鳴き声は、わかりません");
  }

  //静的メソッド
  static int count() {
    return 10;
  }
}

class Dog implements Animal {

  @Override
  public void sound() {
    System.out.println("鳴き声は、わんわんです");
  }
}

public class Main {
  public static void main(String[] args) {

    Animal a = new Dog();
    a.sound(); // 鳴き声は、わんわんです

    System.out.println(Animal.count()); // 10
  }
}

上記のソースコードでは、

Animalインタフェースにおいて、
デフォルトメソッドとしてsound()メソッドを定義しています。

sound()メソッドは、インタフェースを実装するDogクラスによってオーバーライドされています。

Animalインタフェースには、
静的メソッドとしてcount()メソッドを定義しています。

このメソッドは、Animalインタフェース名で呼び出すことができます。

一つ以上の抽象メソッドを持つ、抽象クラス

抽象クラスとは、一つ以上の抽象メソッドを持つクラスです。

抽象メソッドとは、宣言だけがあって実装がないメソッドです。

抽象クラスは、サブクラスに共通の属性や振る舞いを提供するために使われます。

抽象クラスは、単一継承だけサポートします。
一つのクラスは、一つの抽象クラスだけ継承できます。

抽象クラスを継承するクラスは、抽象メソッドを全てオーバーライドしなければなりません。

インスタンス化できる完全な型、具象クラス

具象クラスとは、抽象メソッドを持たないクラスです。

具象クラスは、インスタンス化できる完全な型です。

具象クラスは、インタフェースや抽象クラスから継承したメソッドを実装することで、多様な振る舞いを持つことができます。

【まとめ記事】へのリンク

【まとめ記事】Javaアプリの品質を保つため、Javaソースコードを書くための工夫

Javaソースコードを正しく書くための、ちょっとした工夫について、ご紹介しています。 変数の寿命を限定する書き方。 肯定的な条件を優先して条件分岐する書き方。 クラス…