Developer

【はじめてのJava】インタフェースの使い方【インタフェース編】
2021.10.30
Lv1

【はじめてのJava】インタフェースの使い方【インタフェース編】

はじめてのJava

このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。


インタフェース

前回の記事では、インタフェースの概要やクラスとの違いを解説しました。
今回の記事では、「インタフェース」の定義や使い方を解説していきます。

目次


インタフェースの作成

インタフェースを作成する際には、クラスと似たような形で宣言します。
[構文]

1
2
3
4
5
【修飾子】interface インタフェース名 {
     
    インタフェースにメソッドや変数を定義
 
}

インタフェースを定義する際に注意しなければいけない点が2つあります。

1.変数を定義する際には、「public」「static」「final」として定義しなければいけない。

インタフェースの中で変数を定義する場合、アクセス修飾子を付けずに定義しても暗黙的に上記の3つの修飾子がつけられます。
ここで、気を付けなければいけないものは「final」になります。
final」を付けて定義された変数は、それ以降に変更(値の代入)ができなくなりますので、定義する際に初期値を代入して定義する必要があります。

1
2
3
4
5
6
7
8
9
public interface TestInterface{
     
    int a = 10; // 修飾子を付けていないが、「public static final int a = 10;」と定義したことになる!
     
    public static final int b = 20; // もちろん、修飾子を記述してもOK!
     
    int c ; //「final」の修飾子があることになるので、初期化していないとコンパイルエラーになる!
}

2.メソッドを定義する際には、「public」「abstract」として定義しなければならない。

インタフェースの中でメソッドを定義する場合、アクセス修飾子をつけずに定義しても上記の2つの修飾子がつきます。
ここで、気を付けなければならないものは「abstract」になります。
abstract」という修飾子は抽象メソッドを定義する際に利用する修飾子であるため、通常の形式でメソッドを定義しようとしてもコンパイルエラーになってしまいます。

1
2
3
4
5
6
7
8
9
10
11
12
public interface TestInterface{
     
    void methodA(int num); // 修飾子を付けていないが、「public abstract void methodA(int num);」と定義したことになる!
                             // 抽象メソッドを定義する時の記述でメソッドを定義する!
     
    public abstract void methodB(int num); // もちろん、修飾子を記述して定義してもOK!
     
    void methodC(int num){
        Sytem.out.println("メソッドC"); // 「abstract」がつくので、通常のメソッドを定義する記述を行うとコンパイルエラーになってしまいます。
    }
}

Java1.8からは特殊な記述を行うことで、抽象メソッドでない通常のメソッドを記述することができるようになりました。
その特殊な記述に関しては、次の記事で紹介します。


インタフェースの実装

初めにも解説したように、インタフェースは、そのままインスタンス化を行うことができません。
インタフェースはクラスを作成する際に、そのクラスの中に「実装」して利用します。
実装する際には「implements」というキーワードを利用します。
インタフェースを実装したクラスでは、実装したインタフェースに定義されている抽象メソッドをすべてオーバーライドする必要があります。
抽象メソッドをオーバーライドする際には、必ず「public」修飾子をつけてオーバーライドしなければなりません。

1
2
3
4
5
【修飾子】 class 実装クラス名 implements インタフェース1,インタフェース2, ... {
     
    インタフェースの中に定義された抽象メソッドをオーバーライドする
     
}

クラスの継承と異なる点は、インタフェースの実装は複数を同時に行うことができるという点です。
クラスを継承する場合、多重継承(複数のクラスを継承してクラスを作成すること)が禁止されています。
インタフェースを実装する際には、implementsキーワードの後にカンマ区切りで指定することにより、複数のインタフェースを実装することが可能です。

インタフェースを実装するサンプルプログラム

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface TestInterface {
     
    int num = 10;
     
    void method();
     
}
public class Test implements TestInterface {
     
    public void method(){
        System.out.println("オーバーライドしたメソッド");
    }
 
}

インタフェースの継承

インタフェースもクラスと同じように継承を行うことができます。
インタフェースを継承することで、あるインタフェースの変数やメソッドを引き継いだサブインタフェースを作成することができます。
継承して作成されたインタフェースを実装する場合、継承もとになったインタフェースに定義されている抽象メソッドもすべてオーバーライドする必要があります。
インタフェースの継承を行う際にはクラスと同じように「extends」で継承したインタフェースを作成することができます。

1
2
3
4
5
6
7
8
9
10
11
public interface SuperInterface {
 
    public abstract void method();
 
}
 
public interface SubInterface extends SuperInterface{ //「SuperInterafce」を継承してインタフェースを作成する。
 
    public void method2();
 
}

また、インタフェースを継承する際には、クラスとは異なり複数継承が可能になっています。
複数継承を行う場合、注意しなければならない項目がいくつかあります。
・継承もとになるインタフェースに同じ名前の変数が定義されている場合、呼び出す際に、「インタフェース名.変数名」のように呼び出しを行わないとコンパイルエラーになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interface SuperInterfaceA {
 
    int num = 10; //継承もとになる2つのクラスに同じ名前の変数が定義されている
 
    public abstract void method();
 
}
 
interface SuperInterfaceB {
 
    int num = 20; //継承もとになる2つのクラスに同じ名前の変数が定義されている
 
    public abstract void method();
 
}
 
interface SubInterface extends SuperInterface{ //「SuperInterafceA」と「SuperInterafceB」を継承してインタフェースを作成する。
 
    public void method2();
 
}
class Test implements SubInterface {
 
    public void method(){
        System.out.println(num); // この場合、継承もとのどちらのインタフェースの「num」かわからないのでコンパイルエラーになる。
    }
 
    public void method2(){
        System.out.println(SuperInterfaceA.num); //「SuperInterfaceA」に定義された「num」と指定しているので問題なく呼び出せる。
    }
 
}

・継承もとになるインタフェースに同じ名前で戻り値のデータ型が異なるメソッドが定義されているとコンパイルエラーになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface SuperInterfaceA {
 
    public abstract int method();
 
}
 
interface SuperInterfaceB {
 
    public abstract String method();
 
}
 
interface SubInterface extends SuperInterface{
/*「SuperInterafceA」と「SuperInterafceB」のどちらにも「method」というメソッドがあるが、
   2つの戻り値のデータ型が異なるため、コンパイルエラーになる。 */
}

インタフェース編・次回の内容

今回はインタフェースの概要について紹介しました。
次回は、Java1.8からインタフェースの中に記述できるようになった「defaultメソッド」と「staticメソッド」の使い方を解説していきます。


初めてのJavaシリーズの目次はこちら
インタフェース編の記事一覧はこちら


java 11 の練習問題一覧はこちら
はじめてのJavaシリーズの練習問題一覧はこちら