抽象クラスとインターフェイスはどちらもオブジェクト指向プログラミングでコントラクトを定義するために使用されますが、それらの間にはいくつかの重要な違いがあります。
抽象クラスとインターフェイスの違い:-
定義: 抽象クラスはインスタンス化できず、抽象メソッドと非抽象メソッドの両方を含めることができるクラスです。一方、インターフェイスは、クラスが実装する必要があるメソッドのセットを指定するコントラクトです。
メソッドの実装: 抽象クラスでは、一部のメソッドは実装できますが、その他のメソッドは抽象のままです。つまり、実装がなく、具体的なサブクラスによってオーバーライドする必要があります。対照的に、インターフェイス内のすべてのメソッドはデフォルトで抽象メソッドであり、インターフェイスを実装するクラスによって実装される必要があります。
継承: クラスは 1 つの抽象クラスからのみ継承できますが、複数のインターフェイスを実装できます。これは、抽象クラスがオブジェクトのタイプを表すのに対し、インターフェイスは一連の動作を表すためです。
アクセス修飾子: 抽象クラスはメソッドやプロパティに対して public、protected、private などのアクセス修飾子を持つことができますが、インターフェイスは public アクセスのみを持つことができます。
変数: 抽象クラスはメンバー変数を持つことができますが、インターフェイスは持つことができません。
要約すると、抽象クラスは、継承する具体的なサブクラスの基本クラスを提供するために使用され、インターフェイスは、クラスが実装する必要があるメソッドのセットを定義するために使用されます。抽象クラスは実装されたメソッドと抽象メソッドを持つことができますが、インターフェイスは抽象メソッドのみを持つことができます。クラスは 1 つの抽象クラスのみを継承できますが、複数のインターフェイスを実装できます。
ご存知のとおり、抽象化とは、機能の内部実装を非表示にし、機能のみをユーザーに表示することを指します。つまり、必要な機能のみを表示し、それらの機能がバックグラウンドでどのように実装されるかを非表示にします。一方、インターフェイスは Java で抽象化を実現する別の方法です。両方 抽象クラス そして インターフェース は抽象化に使用されます。以降、インターフェイスと抽象クラスが必須の前提条件となります。
手動テスト

抽象クラスとインターフェイス
- メソッドの種類: インターフェイスには抽象メソッドのみを含めることができます。一方、抽象クラスは抽象メソッドと具象メソッドを持つことができます。 Java 8 からは、デフォルトメソッドと静的メソッドも持つことができます。 Java 9 以降では、プライベートの具象メソッドも持つことができます。
- 注: 具象メソッドは完全な定義を持つメソッドですが、継承されたクラスでオーバーライドすることもできます。しかし、具体的な方法を次のようにすると、 最後の メソッドを最終手段として宣言するため、継承されたクラスでオーバーライドすることはできません。 その実装は完了しました 。
- 最終的な変数: Java インターフェースで宣言された変数は、デフォルトでは Final です。抽象クラスには非最終変数を含めることができます。
- 変数の種類: 抽象クラスには、最終変数、非最終変数、静的変数、および非静的変数を含めることができます。インターフェイスには静的変数と最終変数のみがあります。
- 実装: 抽象クラスはインターフェイスの実装を提供できます。インターフェイスは抽象クラスの実装を提供できません。
- 継承と抽象化: Java インターフェースは、キーワードを使用して実装できます。 実装する 抽象クラスはキーワードを使用して拡張できます。 伸びる 。
- 複数の実装: インターフェイスは 1 つ以上の Java インターフェイスを拡張できます。抽象クラスは別の Java クラスを拡張し、複数の Java インターフェイスを実装できます。
- 多重継承: 多重継承は、 インターフェース を使用すると部分的に実現できますが、抽象クラスを使用すると同じことはできません。 Java では、1 つのクラスは複数のインターフェイスを実装できますが、1 つのクラスを他の複数のクラスから拡張することはできません。これは、ダイヤモンドの問題につながるため、Java では不可能だからです。
- データメンバーのアクセシビリティ: Java インターフェースのメンバー (変数) は、デフォルトでは Final です。 Java 抽象クラスには、private、protected などのクラス メンバーを含めることができます。
抽象クラスの特徴:-
抽象クラスは、オブジェクト指向プログラミングにおける特別なタイプのクラスであり、直接インスタンス化することはできません。代わりに、他のクラスの派生元となるブループリントまたはテンプレートとして機能します。抽象クラス:
- インスタンス化できません : 抽象クラスは直接インスタンス化できません。つまり、抽象クラスのオブジェクトを作成できません。
- 少なくとも 1 つの純粋仮想関数が含まれています : 抽象クラスには少なくとも 1 つの純粋仮想関数が含まれている必要があります。つまり、関数には実装がなく、派生クラスによって実装される必要があります。
- 抽象メソッドと非抽象メソッドの両方を含めることができます : 抽象クラスは、抽象メソッドと非抽象メソッドの両方を持つことができます。非抽象メソッドには完全な実装があり、直接呼び出すことができます。
- コンストラクターとデストラクターを使用できる : 抽象クラスには、他のクラスと同様にコンストラクターとデストラクターを含めることができます。
- メンバー変数を持つことができます : 抽象クラスは、クラスのオブジェクトに属する変数であるメンバー変数を持つことができます。
- 基本クラスとして使用可能 : 抽象クラスは他のクラスの基本クラスとして使用できます。つまり、抽象クラスは他のクラスに継承できます。
全体として、抽象クラスは、複数の関連クラスで共有できる共通のインターフェイスまたは動作を定義するために使用されますが、各派生クラスには特定の実装が含まれます。
例 1: (抽象クラスの場合)
ジャワ abstract class sunstar { abstract void printInfo(); } class employee extends sunstar { void printInfo() { String name = 'avinash'; int age = 21; float salary = 222.2F; System.out.println(name); System.out.println(age); System.out.println(salary); } } class base { public static void main(String args[]) { sunstar s = new employee(); s.printInfo(); } }> 出力
avinash 21 222.2>
例 2: (抽象クラスの場合)
ジャワ // Java Program to Illustrate Concept of // Abstract Class // Importing required classes import java.io.*; // Class 1 // Helper abstract class abstract class Shape { // Declare fields String objectName = ' '; // Constructor of this class Shape(String name) { this.objectName = name; } // Method // Non-abstract methods // Having as default implementation public void moveTo(int x, int y) { System.out.println(this.objectName + ' ' + 'has been moved to' + ' x = ' + x + ' and y = ' + y); } // Method 2 // Abstract methods which will be // implemented by its subclass(es) abstract public double area(); abstract public void draw(); } // Class 2 // Helper class extending Class 1 class Rectangle extends Shape { // Attributes of rectangle int length, width; // Constructor Rectangle(int length, int width, String name) { // Super keyword refers to current instance itself super(name); // this keyword refers to current instance itself this.length = length; this.width = width; } // Method 1 // To draw rectangle @Override public void draw() { System.out.println('Rectangle has been drawn '); } // Method 2 // To compute rectangle area @Override public double area() { // Length * Breadth return (double)(length * width); } } // Class 3 // Helper class extending Class 1 class Circle extends Shape { // Attributes of a Circle double pi = 3.14; int radius; // Constructor Circle(int radius, String name) { // Super keyword refers to parent class super(name); // This keyword refers to current instance itself this.radius = radius; } // Method 1 // To draw circle @Override public void draw() { // Print statement System.out.println('Circle has been drawn '); } // Method 2 // To compute circle area @Override public double area() { return (double)((pi * radius * radius)); } } // Class 4 // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating the Object of Rectangle class // and using shape class reference. Shape rect = new Rectangle(2, 3, 'Rectangle'); System.out.println('Area of rectangle: ' + rect.area()); rect.moveTo(1, 2); System.out.println(' '); // Creating the Objects of circle class Shape circle = new Circle(2, 'Circle'); System.out.println('Area of circle: ' + circle.area()); circle.moveTo(2, 4); } }> 出力
Area of rectangle: 6.0 Rectangle has been moved to x = 1 and y = 2 Area of circle: 12.56 Circle has been moved to x = 2 and y = 4>
長方形と円の間に共通のコードがない場合は、インターフェイスを使用することになります。
インターフェース:
インターフェースの特徴:
インターフェース:
- 一連のメソッドとプロパティを定義します。 インターフェイスは、インターフェイスを実装するクラスまたは構造体によって実装される必要があるメソッドとプロパティのセットを定義します。
- 共通プロトコルを提供します。 インターフェイスは、さまざまなソフトウェア コンポーネントが相互に通信できるようにする共通のプロトコルを提供します。
- ポリモーフィズムをサポートします。 インターフェイスを使用するとポリモーフィズムを実現できます。つまり、異なるクラスのオブジェクトは、同じインターフェイスを実装している限り、同じ型に属しているかのように扱うことができます。
- 懸念事項の分離が可能になります。 インターフェイスにより関心事の分離が可能になります。つまり、インターフェイスの仕様に準拠している限り、ソフトウェア システムのさまざまな部分を互いに独立して開発できるということです。
- コードの再利用性が向上します。 インターフェイスは、同じインターフェイスを実装している限り、さまざまなソフトウェア コンポーネントが同じコード ベースを再利用できるようにすることで、コードの再利用性を向上させます。
- 設計パターンを強制します。 インターフェイスを使用すると、実装クラスによって特定のメソッドまたはプロパティが実装されることを要求することで、アダプター パターンなどの設計パターンを強制できます。
- テストを容易にします: インターフェイスは、インターフェイスを実装するモック オブジェクトを使用して、ソフトウェア コンポーネントを互いに独立してテストできるようにすることでテストを容易にします。
例 1: インターフェースの場合
ジャワ // Java Program to Illustrate Concept of Interface // Importing I/O classes import java.io.*; // Interface interface Shape { // Abstract method void draw(); double area(); } // Class 1 // Helper class class Rectangle implements Shape { int length, width; // constructor Rectangle(int length, int width) { this.length = length; this.width = width; } @Override public void draw() { System.out.println('Rectangle has been drawn '); } @Override public double area() { return (double)(length * width); } } // Class 2 // Helper class class Circle implements Shape { double pi = 3.14; int radius; // constructor Circle(int radius) { this.radius = radius; } @Override public void draw() { System.out.println('Circle has been drawn '); } @Override public double area() { return (double)((pi * radius * radius)); } } // Class 3 // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating the Object of Rectangle class // and using shape interface reference. Shape rect = new Rectangle(2, 3); System.out.println('Area of rectangle: ' + rect.area()); // Creating the Objects of circle class Shape circle = new Circle(2); System.out.println('Area of circle: ' + circle.area()); } }> 出力
Area of rectangle: 6.0 Area of circle: 12.56>
例 2: インターフェースの場合
ジャワ // Java Program to Illustrate Concept of Interface // Importing I/O classes import java.io.*; // Interface interface Shape { // Abstract method void draw(); double area(); } // Class 1 // Helper class class Rectangle implements Shape { int length, width; // constructor Rectangle(int length, int width) { this.length = length; this.width = width; } @Override public void draw() { System.out.println('Rectangle has been drawn '); } @Override public double area() { return (double)(length * width); } } // Class 2 // Helper class class Circle implements Shape { double pi = 3.14; int radius; // constructor Circle(int radius) { this.radius = radius; } @Override public void draw() { System.out.println('Circle has been drawn '); } @Override public double area() { return (double)((pi * radius * radius)); } } // Class 3 // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating the Object of Rectangle class // and using shape interface reference. Shape rect = new Rectangle(2, 3); System.out.println('Area of rectangle: ' + rect.area()); // Creating the Objects of circle class Shape circle = new Circle(2); System.out.println('Area of circle: ' + circle.area()); } }> 出力
Area of rectangle: 6.0 Area of circle: 12.56>
いつ何を使うのか?
次のステートメントのいずれかが状況に当てはまる場合は、抽象クラスの使用を検討してください。
- Java アプリケーションでは、いくつかのコード行を共有する必要がある関連クラスがいくつかあり、これらのコード行を抽象クラス内に置くことができ、この抽象クラスはこれらすべての関連クラスによって拡張される必要があります。
- 抽象クラスで非静的フィールドまたは非最終フィールドを定義すると、メソッドを介して、それらが属するオブジェクトの状態にアクセスして変更できるようになります。
- 抽象クラスを拡張するクラスには、多くの共通のメソッドまたはフィールドがあるか、パブリック以外のアクセス修飾子 (protected や private など) が必要であることが予想されます。
次のステートメントのいずれかが状況に当てはまる場合は、インターフェイスの使用を検討してください。
- これは完全な抽象化であり、インターフェイス内で宣言されたすべてのメソッドは、このインターフェイスを実装するクラスによって実装される必要があります。
- クラスは複数のインターフェイスを実装できます。それを多重継承といいます。
- 特定のデータ型の動作を指定したいが、その動作を誰が実装するかは気にしていません。