インターフェイスと抽象クラスは、抽象化とポリモーフィズムを実現するために不可欠なコンポーネントです。
Java のインターフェイスは、クラスに似た参照型であり、抽象メソッド、静的メソッド、デフォルト メソッド、および静的最終変数 (定数) のみを含めることができます。インターフェイスは、Java で抽象化と多重継承を実現するために使用されます。インターフェースは直接インスタンス化できない場合があります。
?Java 8 より前では、インターフェースには 抽象メソッド のみを含めることができました。
これらのメソッドの実装は、別のクラスで提供する必要があります。したがって、新しいメソッドをインターフェイスに追加する場合は、その実装コードを同じインターフェイスを実装するクラスで提供する必要があります。
?この問題を解決するために、Java 8 では デフォルト メソッド の概念が導入されました。これにより、インターフェースを実装するクラスに影響を与えることなく、インターフェースが実装されたメソッドを持つことができるようになります。 .
必要に応じてクラスを実装することで、デフォルトのメソッドをオーバーライドできます。
Java の抽象クラスは、単独ではインスタンス化できないクラスであり、抽象メソッド (本体のないメソッド) と具象メソッド (本体のあるメソッド) を含む場合があります。抽象クラスは、サブクラスに共通のベースを提供するために使用され、コードの再利用と共有動作の定義を可能にします。
Java は単一継承のみをサポートします。つまり、各クラスは 1 つのクラスのフィールドとメソッドのみを継承できます。複数のソースからプロパティを継承する必要がある場合、Java は 多重継承 の形式である インターフェース の概念を提供します。
?インターフェイスはクラスに似ています。ただし、これらはメソッドのシグネチャのみを定義し、その実装は定義しません。インターフェイスで宣言されたメソッドはクラスに実装されます。 多重継承は、クラスが複数のインターフェースを実装する場合に発生します。
Java では、クラスではなくインターフェイスを通じて多重継承が実現されます。これにより、クラスが複数のインターフェイスを実装し、それぞれのインターフェイスからメソッド シグネチャを継承できるようになります。以下は、インターフェースを使用した多重継承を示す例です。
Flyable と Swimmable という 2 つのインターフェイスと、両方のインターフェイスを実装するクラス Duck を定義しましょう。
public interface Flyable { void fly(); }
public interface Swimmable { void swim(); }
public class Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("Duck is flying"); } @Override public void swim() { System.out.println("Duck is swimming"); } public static void main(String[] args) { Duck duck = new Duck(); duck.fly(); duck.swim(); } }
インターフェース:
クラス:
メインメソッド:
Duck is flying Duck is swimming
関係を説明するための簡単な図を次に示します。
+----------------+ | Flyable |<--------------->Interface |----------------| | + fly() | +----------------+ ^ | | Implements | +----------------+ | Duck |<--------------->Class |----------------| | + fly() | | + swim() | +----------------+ ^ | | Implements | +----------------+ | Swimmable |<--------------->Interface |----------------| | + swim() | +----------------+
この例では、Duck クラスは Flyable インターフェイスと Swimmable インターフェイスの両方を実装することによって多重継承を示しています。これにより、Duck クラスが両方のインターフェースで定義されたメソッドの実装を継承して提供できるようになり、Java がインターフェースを通じて多重継承をどのように実現するかを示します。
Java の抽象クラスは、関連するクラスのファミリーに共通の基盤を提供するために使用されます。これらには、抽象メソッド (本体のないメソッド) と具象メソッド (本体のあるメソッド) の両方を含めることができます。以下は、抽象クラスの使用を示す例です。
抽象クラス Animal と、Animal クラスを拡張する 2 つのサブクラス Dog と Cat を定義しましょう。
public abstract class Animal { // Abstract method (does not have a body) public abstract void makeSound(); // Concrete method (has a body) public void sleep() { System.out.println("The animal is sleeping"); } }
public class Dog extends Animal { @Override public void makeSound() { System.out.println("Dog says: Woof!"); } public static void main(String[] args) { Dog dog = new Dog(); dog.makeSound(); dog.sleep(); } }
public class Cat extends Animal { @Override public void makeSound() { System.out.println("Cat says: Meow!"); } public static void main(String[] args) { Cat cat = new Cat(); cat.makeSound(); cat.sleep(); } }
抽象クラス: 動物
サブクラス: 犬
サブクラス: 猫
犬クラスの場合:
public interface Flyable { void fly(); }
Cat クラスの場合:
public interface Swimmable { void swim(); }
この関係を示す簡単な図は次のとおりです。
public class Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("Duck is flying"); } @Override public void swim() { System.out.println("Duck is swimming"); } public static void main(String[] args) { Duck duck = new Duck(); duck.fly(); duck.swim(); } }
この例では、Animal 抽象クラスが Dog サブクラスと Cat サブクラスに共通のベースを提供します。 Animal クラスは、サブクラスによって実装される必要がある抽象メソッド makeSound() と、デフォルトの実装を提供する具象メソッド sleep() を定義します。 Dog クラスと Cat クラスは Animal クラスを拡張し、独自の makeSound() メソッドの実装を提供します。
Duck is flying Duck is swimming
インターフェイスは、API、フレームワーク、ライブラリを定義するためによく使用されます。たとえば、java.util.List インターフェイスは、ArrayList や LinkedList などのリスト実装のコントラクトを提供します。
+----------------+ | Flyable |<--------------->Interface |----------------| | + fly() | +----------------+ ^ | | Implements | +----------------+ | Duck |<--------------->Class |----------------| | + fly() | | + swim() | +----------------+ ^ | | Implements | +----------------+ | Swimmable |<--------------->Interface |----------------| | + swim() | +----------------+
抽象クラスは、関連するクラスのファミリーに基本クラスを提供するためによく使用されます。たとえば、java.util.AbstractList クラスは List インターフェースの骨格的な実装を提供し、サブクラスが実装する必要があるコードの量を削減します。
public interface Flyable { void fly(); }
SNo | Interface | Abstract Class |
---|---|---|
1 | Interfaces cannot be instantiated | Abstract classes cannot be instantiated |
2 | It can have both abstract and non-abstract methods | It can have both abstract and non-abstract methods |
3 | In interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public | In abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods |
4 | Interface supports multiple inheritance. Multiple interfaces can be implemented | Abstract class or class can extend only one class |
5 | It is used if you expect that unrelated classes would implement your interface. Eg, the interfaces Comparable and Cloneable are implemented by many unrelated classes | It is used if you want to share code among several closely related classes |
6 | It is used if you want to specify the behavior of a particular data type, but not concerned about who implements its behavior. | It is used if you expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private) |
参照: https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
抽象クラスがサブクラス化されると、通常、サブクラスは親クラス内のすべての抽象メソッドの実装を提供します。ただし、そうでない場合は、サブクラスも抽象として宣言する必要があります。
「Effective Java」の著者である Joshua Bloch によると、インターフェイスはより柔軟で多重継承をサポートしているため、型を定義する場合は抽象クラスよりも好まれます。ただし、抽象クラスは、共有機能を提供し、コードの重複を減らすのに役立ちます。
"インターフェイスはミックスインの定義に最適です。対照的に、クラスは固有のプロパティを持つオブジェクトの定義に最適です。"
- ジョシュア・ブロック
独自の Java プロジェクトでインターフェースと抽象クラスの力を試してください。インターフェイスを使用してコントラクトを定義し、抽象クラスを使用して共有機能を提供することを試してください。あなたの洞察や経験を Java コミュニティと共有して、集合的な知識と成長に貢献してください。
この投稿に対する修正や追加は大歓迎です。
public interface Flyable { void fly(); }
以上がJava のインターフェースと抽象クラスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。