Java の interface クラスと abstract クラスの違い

Mohammad Irfan 2023年10月12日
  1. abstract クラス interface の類似点
  2. abstract クラスと interface の違い
  3. 抽象クラスとインターフェイスをいつ使用するのですか
  4. Java の抽象クラス
  5. Java のインターフェース
  6. インターフェイスを実装する抽象クラス
  7. まとめ
Java の interface クラスと abstract クラスの違い

このチュートリアルでは、Java の Interface クラスと Abstract クラスの違いを紹介し、トピックを理解するためのサンプルコードもいくつかリストします。

抽象化は、実装を非表示にし、ユーザーに重要な詳細のみを提供するプロセスです。Java での抽象化は、抽象クラスとインターフェースを介して実現されます。抽象クラスとインターフェースにはいくつかの共通点がありますが、それらの間には大きな違いがあります。最初に、2つの間で類似していることのいくつかを見てみましょう。

abstract クラス interface の類似点

  • 前述のように、抽象化には抽象クラスとインターフェイスの両方が使用されます。
  • 抽象クラスとインターフェースはインスタンス化できません。つまり、それらのオブジェクトを作成できません。
  • サブクラスは、抽象クラスまたはインターフェースで定義された抽象メソッドをオーバーライドする必要があります。

上記の点は、2つの間の類似点をほぼ要約しています。次に、それらの主な違いのいくつかを見てみましょう。

abstract クラスと interface の違い

abstract クラス interface
Java の abstract キーワードは、abstract クラスを作成または宣言するために使用されます。 Java では、interface キーワードを使用して、新しいインターフェースを作成または宣言します。
クラスは、extends キーワードを使用して、抽象クラスのプロパティとメソッドを継承できます。 Java でインターフェイスを実装するには、implements キーワードを使用できます。
抽象クラスには、抽象メソッドまたは非抽象メソッドを定義できます。抽象メソッドは、実装が提供されていないメソッドです。 インターフェイスには、抽象メソッドのみを含めることができます。メソッド定義のみを提供でき、その実装は提供できません。Java 8 以降、Interfaces にデフォルトメソッドと静的メソッドを含めることもできます。
抽象クラスには、最終変数または非最終変数(クラス属性)を含めることができます。また、静的または非静的属性を含めることもできます。 インターフェイスには静的メンバーと最終メンバーのみを含めることができ、他のタイプのメンバーは許可されません。
抽象クラスは、インターフェイスを実装し、インターフェイスのメソッドを実装できます。 インターフェイスは他のクラスを拡張したり、抽象クラスメソッドをオーバーライドまたは実装したりすることはできません。
抽象クラスは他のクラスを拡張でき、インターフェースを実装することもできます。 前のポイントで説明したように、インターフェイスは他のクラスを拡張できません。ただし、インターフェースの実装に制限はありません。
Java は、クラスを介した多重継承をサポートしていません。抽象クラスは、他のクラスと同様に、多重継承をサポートしていません。 Java での多重継承のサポートは、インターフェースを介して提供されます。これは、インターフェースが完全な抽象化を提供するためです。
抽象クラスのメンバーまたは属性は、プライベート、保護、またはパブリックにすることができます。 インターフェイスの属性またはメンバーは常にパブリックです。

抽象クラスとインターフェイスをいつ使用するのですか

抽象クラスは、部分的または完全な抽象化を提供できます。一方、インターフェースは常に完全な抽象化を提供します。いくつかの共通の機能を持ついくつかのクラスに対して、抽象親クラスが作成される場合があります。より自由な行動が必要な場合は、抽象クラスも推奨されます。

基本的な構造を定義する場合は、インターフェースが推奨されます。プログラマーは、この構造で何でも構築できます。インターフェースは多重継承もサポートします。したがって、1つのクラスで複数のインターフェイスを実装できます。

全体として、それは選択の問題であり、達成する必要のあるタスクです。抽象クラスとインターフェイスはどちらもさまざまな目的に適しており、それに応じて使用する必要があります。

Java の抽象クラス

抽象クラスを作成し、それを拡張して抽象クラスとその機能を理解する子クラスを作成しましょう。

abstract class Bell {
  protected String sound;

  Bell() {
    this.sound = "ting";
  }
  // Abstract Method
  abstract public void ring();

  // Non-Abstract Methods
  public void increaseVolume() {
    System.out.println("Increasing Volume");
  }

  public void decreaseVolume() {
    System.out.println("Decreasing Volume");
  }
}
class SchoolBell extends Bell {
  @Override
  public void ring() {
    System.out.println("Ringing the School bell: " + sound);
  }
}
class ChruchBell extends Bell {
  @Override
  public void ring() {
    System.out.println("Ringing the Chruch Bell: " + sound);
  }
}
public class AbstractClassDemo {
  public static void main(String[] args) {
    SchoolBell sb = new SchoolBell();
    ChruchBell cb = new ChruchBell();

    // Using the overridden methods
    sb.ring();
    cb.ring();

    // Using the non-abstract methods of Bell class
    sb.increaseVolume();
    cb.decreaseVolume();
  }
}

出力:

Ringing the School bell: ting
Ringing the Chruch Bell: ting
Increasing Volume
Decreasing Volume

Java のインターフェース

インターフェイスを使用して同じシナリオを複製してみましょう。インターフェイスで非抽象メソッドを定義できなくなりました。クラスが increaseVolume() メソッドと decreaseVolume() メソッドの共通の実装を望まない場合は、インターフェイスが正しい選択です。

interface Bell {
  String sound = "ting";
  // only abstract methods allowed in interface
  public void ring();
  public void increaseVolume();
  public void decreaseVolume();
}
class SchoolBell implements Bell {
  public void ring() {
    System.out.println("Ringing the School bell: " + sound);
  }
  @Override
  public void increaseVolume() {
    System.out.println("Increasing Volume of School Bell");
  }
  @Override
  public void decreaseVolume() {
    System.out.println("Decreasing Volume of School Bell");
  }
}
class ChruchBell implements Bell {
  public void ring() {
    System.out.println("Ringing the Chruch Bell: " + sound);
  }
  @Override
  public void increaseVolume() {
    System.out.println("Increasing Volume of Chruch Bell");
  }
  @Override
  public void decreaseVolume() {
    System.out.println("Decreasing Volume of Chruch Bell");
  }
}
public class InterfaceDemo {
  public static void main(String[] args) {
    SchoolBell sb = new SchoolBell();
    ChruchBell cb = new ChruchBell();

    // Using the overridden methods
    sb.ring();
    cb.ring();

    // Using the non-abstract methods of Bell class
    sb.increaseVolume();
    cb.decreaseVolume();
  }
}

出力:

Ringing the School bell: ting
Ringing the Chruch Bell: ting
Increasing Volume of School Bell
Decreasing Volume of Chruch Bell

インターフェイスを実装する抽象クラス

前のセクションで説明したように、インターフェイスのメソッドを抽象クラスに実装できます。次のコードはこれを示しています。

interface Bell {
  String sound = "ting";
  // only abstract methods allowed in interface
  public void ring();
  public void increaseVolume();
  public void decreaseVolume();
}
abstract class AbstractBell implements Bell {
  public void increaseVolume() {
    System.out.println("Increasing Volume");
  }
  public void decreaseVolume() {
    System.out.println("Decreasing Volume");
  }
}

まとめ

抽象化は、オブジェクト指向プログラミングで使用される最も基本的な概念の 1つです。抽象化は、実装を非表示にし、ユーザーに最小限の重要な詳細のみを提供するために使用されます。Java では、抽象化は抽象クラスまたはインターフェースを使用して行われます。2つの主な違いは、抽象クラスは部分的な抽象化も提供できるのに対し、インターフェイスは常に完全な抽象化を提供することです。このチュートリアルでは、2つの主な違いのいくつかについて説明しました。

関連記事 - Java Interface