1. 概要

このチュートリアルでは、Javaのインターフェースについて説明します。 また、Javaがそれらを使用してポリモーフィズムと多重継承を実装する方法についても説明します。

2. Javaのインターフェースとは何ですか?

Javaでは、インターフェースはメソッドと定数変数のコレクションを含む抽象型です。 これはJavaのコアコンセプトの1つであり、抽象化、ポリモーフィズム、および多重継承を実現するために使用されます。

Javaのインターフェースの簡単な例を見てみましょう。

public interface Electronic {

    // Constant variable
    String LED = "LED";

    // Abstract method
    int getElectricityUse();

    // Static method
    static boolean isEnergyEfficient(String electtronicType) {
        if (electtronicType.equals(LED)) {
            return true;
        }
        return false;
    }

    //Default method
    default void printDescription() {
        System.out.println("Electronic Description");
    }
}

implements キーワードを使用して、Javaクラスにインターフェースを実装できます。

次に、作成したElectronicインターフェイスを実装するComputerクラスも作成しましょう。

public class Computer implements Electronic {

    @Override
    public int getElectricityUse() {
        return 1000;
    }
}

2.1. インターフェイスを作成するためのルール

インターフェースでは、以下を使用できます。

また、次のことも覚えておく必要があります。

  • インターフェイスを直接インスタンス化することはできません
  • インターフェイスは空で、メソッドや変数は含まれていません。
  • インターフェイス定義でfinalワードを使用することはできません。これは、コンパイラエラーが発生するためです。
  • すべてのインターフェース宣言には、publicまたはデフォルトのアクセス修飾子が必要です。 abstract修飾子はコンパイラーによって自動的に追加されます
  • インターフェイスメソッドを保護または最終にすることはできません
  • Java 9までは、インターフェースメソッドをprivateにすることはできませんでした。 ただし、Java 9では、インターフェイスでプライベートメソッドを定義する可能性が導入されました
  • インターフェイス変数は、定義上、 public static 、およびfinalです。 可視性を変更することは許可されていません

3. それらを使用して何を達成できますか?

3.1. 行動機能

インターフェイスを使用して、無関係のクラスで使用できる特定の動作機能を追加します。 たとえば、 Compareable コンパレータ、および Cloneable は、無関係のクラスで実装できるJavaインターフェイスです。 以下は、Employeeクラスの2つのインスタンスを比較するために使用されるComparatorインターフェイスの例です。

public class Employee {

    private double salary;

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

public class EmployeeSalaryComparator implements Comparator<Employee> {

    @Override
    public int compare(Employee employeeA, Employee employeeB) {
        if (employeeA.getSalary() < employeeB.getSalary()) {
            return -1;
        } else if (employeeA.getSalary() > employeeB.getSalary()) { 
            return 1;
        } else {
            return 0;
        }
    }
}

詳細については、ComparatorおよびComparableinJavaに関するチュートリアルをご覧ください。

3.2. 多重継承

Javaクラスは、特異な継承をサポートします。 ただし、インターフェースを使用することで、多重継承を実装することもできます。

たとえば、次の例では、CarクラスFlyおよびTransformインターフェイスを実装していることがわかります。 そうすることで、メソッドflyおよびtransformを継承します。

public interface Transform {
    void transform();
}

public interface Fly {
    void fly();
}

public class Car implements Fly, Transform {

    @Override
    public void fly() {
        System.out.println("I can Fly!!");
    }

    @Override
    public void transform() {
        System.out.println("I can Transform!!");
    }
}

3.3. ポリモーフィズム

質問をすることから始めましょう:ポリモーフィズムとは何ですか? これは、実行時にオブジェクトがさまざまな形式をとる機能です。 具体的には、実行時に特定のオブジェクトタイプに関連するオーバーライドメソッドの実行です。

Javaでは、インターフェースを使用してポリモーフィズムを実現できます。 たとえば、インターフェースはさまざまな形をとることができます—それはサークルまたは四角。

Shapeインターフェースを定義することから始めましょう。

public interface Shape {
    String name();
}

次に、Circleクラスも作成しましょう。

public class Circle implements Shape {

    @Override
    public String name() {
        return "Circle";
    }
}

また、 Square クラス:

public class Square implements Shape {

    @Override
    public String name() {
        return "Square";
    }
}

最後に、Shapeインターフェースとその実装を使用してポリモーフィズムの動作を確認します。 いくつかのShapeオブジェクトをインスタンス化し、それらを List に追加し、最後にそれらの名前をループで出力してみましょう。

List<Shape> shapes = new ArrayList<>();
Shape circleShape = new Circle();
Shape squareShape = new Square();

shapes.add(circleShape);
shapes.add(squareShape);

for (Shape shape : shapes) {
    System.out.println(shape.name());
}

4. インターフェイスのデフォルトメソッド

Java 7以下の従来のインターフェースは、下位互換性を提供しません。

つまり、 Java 7以前で記述されたレガシーコードがあり、既存のインターフェイスに抽象メソッドを追加する場合、そのインターフェイスを実装するすべてのクラスが新しい抽象メソッドをオーバーライドする必要があります 。 そうしないと、コードが壊れます。

Java 8は、オプションでインターフェースレベルで実装できるデフォルトのメソッドを導入することにより、この問題を解決しました。

5. インターフェイスの継承ルール

インターフェイスを介して多重継承を実現するには、いくつかのルールを覚えておく必要があります。 これらについて詳しく見ていきましょう。

5.1. 別のインターフェースを拡張するインターフェース

インターフェイスが別のインターフェイスをextendsすると、そのインターフェイスのすべての抽象メソッドを継承します。 HasColorShapeの2つのインターフェイスを作成することから始めましょう。

public interface HasColor {
    String getColor();
}

public interface Box extends HasColor {
    int getHeight()
}

上記の例では、 Box は、キーワードextendsを使用してHasColorから継承します。これにより、BoxインターフェイスはgetColorを継承します。 。 その結果、 Box インターフェースには、getColorgetHeightの2つのメソッドが含まれるようになりました。

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

抽象クラスがインターフェイスを実装すると、その抽象メソッドとデフォルトメソッドがすべて継承されます。 Transformインターフェースとそれを実装するabstractクラスVehicleについて考えてみましょう。

public interface Transform {
    
    void transform();
    default void printSpecs(){
        System.out.println("Transform Specification");
    }
}

public abstract class Vehicle implements Transform {}

この例では、 Vehicle クラスは、抽象transformメソッドとデフォルトのprintSpecsメソッドの2つのメソッドを継承します。

6. 機能インターフェイス

Javaには、 Compareable (Java 1.2以降)や Runnable (Java 1.0以降)など、初期の頃から多くの機能インターフェイスがありました。

Java 8では、 Predicate Consumer Functionなどの新しい機能インターフェイスが導入されました。 これらの詳細については、 Java8の機能インターフェイスに関するチュートリアルをご覧ください。

7. 結論

このチュートリアルでは、Javaインターフェースの概要を説明し、それらを使用してポリモーフィズムと多重継承を実現する方法について説明しました。

いつものように、完全なコードサンプルはGitHubで入手できます。