javaのインターフェースは、コアの概念の一つです。 Javaのインターフェースは、Javaプログラミング言語の中核部分であり、JDKだけでなくJavaデザインパターンでも広く使用されています。ほとんどのフレームワークでは、Javaのインターフェースが重要な役割を果たしています。
Javaのインターフェース
Javaのインターフェースは抽象化を実現する方法を提供します。Javaのインターフェースは、サブクラスが実装するための契約を定義するためにも使用されます。たとえば、複数の形状で構成される図を作成したいとします。ここで、
Shape
というインターフェースを作成し、異なる種類の形状オブジェクトが実装するすべてのメソッドを定義できます。簡略化のために、draw()
メソッドで形状を描画し、getArea()
メソッドで形状の面積を返すだけとします。
Javaのインターフェースの例
上記の要件に基づいて、Shapeインターフェースは次のようになります。Shape.java
package com.journaldev.design;
public interface Shape {
//暗黙的にpublic、static、final
public String LABLE="Shape";
//インターフェースメソッドは暗黙的に抽象的で公開されています
void draw();
double getArea();
}
Javaでのインターフェースに関する重要なポイント
-
interface
はJavaでインターフェースを作成するために使用されるコードです。 -
Javaではインターフェースをインスタンス化することはできません。
-
インターフェースは絶対的な抽象化を提供します。前の投稿で、Javaでの抽象クラスについて学習しました抽象化を提供するが、抽象クラスにはメソッドの実装を持つことができますが、インターフェースはできません。
-
インターフェースにはコンストラクタを持つことはできません。インスタンス化することができないため、インターフェースには本体を持つメソッドを持つことはできません。
-
デフォルトで、インターフェースの任意の属性は public, static, final ですので、属性にアクセス修飾子を提供する必要はありませんが、提供したとしても、コンパイラはそれについて文句を言いません。
-
デフォルトで、インターフェースのメソッドは暗黙的に abstract かつ public です。これは、メソッドには本体がないため、サブクラスがメソッドの実装を提供できるようにするため、合理的です。
-
インターフェースはクラスを拡張することはできませんが、他のインターフェースを拡張することはできます。
public interface Shape extends Cloneable{}
は、他のインターフェースを拡張するインターフェースの例です。実際、Javaはインターフェースでの多重継承を提供しています。これは、インターフェースが複数のインターフェースを拡張できることを意味します。 -
implements
キーワードは、クラスがインターフェースを実装するために使用されます。 -
インターフェースを実装するクラスは、抽象クラスでない限り、すべてのメソッドの実装を提供しなければなりません。たとえば、次のように抽象クラスで上記のインターフェースを実装できます:
ShapeAbs.java
package com.journaldev.design; public abstract class ShapeAbs implements Shape { @Override public double getArea() { // TODO Auto-generated method stub return 0; } }
-
実装クラスが常に実装を提供することを事前に知っているため、実装ではなくインターフェースの観点でプログラムを記述するように常に努めるべきです。そして、将来、より良い実装が到着した場合には簡単に切り替えることができます。
Java インターフェース実装例
さて、Java での Shape インターフェースの実装をいくつか見てみましょう。Circle.java
package com.journaldev.design;
public class Circle implements Shape {
private double radius;
public Circle(double r){
this.radius = r;
}
@Override
public void draw() {
System.out.println("Drawing Circle");
}
@Override
public double getArea(){
return Math.PI*this.radius*this.radius;
}
public double getRadius(){
return this.radius;
}
}
Circleクラスには、インターフェースで定義されたすべてのメソッドが実装されており、getRadius()
などの独自のメソッドもあります。 インターフェースの実装には複数の種類のコンストラクタがある場合があります。 Shapeインターフェースの別の実装を見てみましょう。 Rectangle.java
package com.journaldev.design;
public class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double w, double h){
this.width=w;
this.height=h;
}
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
@Override
public double getArea() {
return this.height*this.width;
}
}
Override注釈の使用に注目し、Javaのアノテーションについて学び、Javaでメソッドをオーバーライドする際には常にOverride注釈を使用する理由を理解してください。 インターフェースと実装という用語を使ってコーディングする方法を示すテストプログラムが以下にあります。 ShapeTest.java
package com.journaldev.design;
public class ShapeTest {
public static void main(String[] args) {
//インターフェースではなく実装をプログラムする
Shape shape = new Circle(10);
shape.draw();
System.out.println("Area="+shape.getArea());
//簡単に実装を切り替える
shape=new Rectangle(10,10);
shape.draw();
System.out.println("Area="+shape.getArea());
}
}
上記のJavaインターフェースの例プログラムの出力は次のとおりです:
Drawing Circle
Area=314.1592653589793
Drawing Rectangle
Area=100.0
Javaインターフェースの利点
- インターフェースはすべての実装クラスに対する契約を提供するため、インターフェースを使用してコーディングするのが良いです。実装クラスは使用しているメソッドを削除することができません。
- インターフェースは、タイプを定義し、コードのトップレベル階層を作成するための出発点として適しています。
- Javaクラスは複数のインターフェースを実装できるため、ほとんどの場合はインターフェースをスーパークラスとして使用する方が良いです。
Javaインターフェースの欠点
インターフェースは多くの利点を提供しますが、いくつかの欠点もあります。
-
プロジェクトの設計時にはインターフェースのメソッドを非常に慎重に選択する必要があります。後でインターフェースからメソッドを追加または削除することはできません。これにより、すべての実装クラスでコンパイルエラーが発生します。これにより、多くのインターフェースが基本インターフェースを拡張するようなコードが生じ、メンテナンスが困難になる場合があります。
-
実装クラスに独自のメソッドがある場合、Objectの型がそれらのメソッドを持たないインターフェースであるため、コード内で直接使用することはできません。
Circle c = (Circle) shape; c.getRadius();
クラスの型変換には独自の欠点があります。
これがJavaのインターフェースに関する情報です。Javaのインターフェースを多く使用するので、その特徴を把握しておく必要があります。システムの設計やクライアントとインターフェースを実装するサブクラスとの契約としてインターフェースを使用してください。更新:Java 8では、デフォルトメソッドと静的メソッドの実装を導入することで、インターフェースの定義が変更されています。詳細については、Java 8インターフェースをご覧ください。
Source:
https://www.digitalocean.com/community/tutorials/interface-in-java