1. Top
  2. Java SE
  3. インタフェース

インタフェース(interface)

インタフェースとは

インタフェースとは、ある特定の機能の概要を記述したもので、簡単に言ってしまえば、「定数とメソッドの宣言を一つにまとめたもの」となります。あるインタフェースを実装したクラスは、同一のインタフェースを実装したクラス間でインタフェースで定義された機能の実装を共通して持っていることになります。

インタフェースは前回説明した[ 抽象クラス ]と似ており、自体をインスタンス化することが出来ません。また、あるインタフェースを実装した場合、実装したクラスではインタフェースで定義されているメソッド全てを実装しなければなりません。

実装を強制するだけであれば抽象クラスを使用すれば良いので使用する必要性に疑問を感じるかも知れませんが、インタフェースの利点としては、クラスが複数のインタフェースを実装できる点と、インタフェースの実装が、クラス関係に依存しないことです。


インタフェースには以下のようなルールがあります。

1、インタフェースのオブジェクトを生成することはできません。
2、インタフェースを実装したクラスは宣言されているメソッドを実装しなければなりません。
3、インタフェース内で定義した変数は、定数になり変更することができません。

※同一名称のメソッドで、同じ仮引数、戻り値を持つメソッドが複数のクラスに存在したとして、Javaではこれらのクラスを継承した場合、コンパイラがどちらのメソッドを呼び出すか判断できないため、多重継承は認められていません。


ページの先頭へ

インタフェースの定義

インタフェースを定義する。

先ずインタフェースを定義するには、「 interface 」キーワードを使用します。
今回は携帯電話の機能として、カメラ付きを定義するインターフェースを作って見ましょう。
interface WithCamera {

    // カメラを撮る
    public void shootPhotograph();

    // 画素数を返す
    public long getPixel();

}

上記インタフェースでは、カメラを撮るメソッドと、カメラの画素数を返すメソッドを定義しておきました。このインタフェースを実装する場合は、これら二つのメソッドを実装する必要があります。また、インタフェース名の前に public や protected といったアクセス権を規定する修飾子を付加することも可能です。


インタフェースを実装する。

次にクラスからインタフェースを実装する方法です。
インタフェースを実装する場合は「 implements 」キーワードを使用します。
class MobilePhoneA implements WithCamera {

    // カメラを撮る実装を定義
    public void shootPhotograph(){
        System.out.println("写真を撮ります");
    }

    // 画素数を返す実装を定義
    public long getPixel(){
       return (long)4000000;
    }

    // 機器名を返す
    public String getModelName(){
       return "abc 560";
    }

}

このようにインタフェースで定義されている、「 getPixel 」と「 getModelName 」二つのメソッドをこのクラスで実装しています。実装しているインタフェースで定義されたメソッドを実装しないとコンパイルエラーとなります。 逆に言うと、インタフェースを実装していると言うことは、そのクラスでその機能を実装しているということを意味しています。

上記では一つのインタフェースしか実装していませんが、インタフェース名をカンマで区切り複数のインタフェースを実装することも出来ます。


ページの先頭へ

インタフェースの利用

今度は定義したインタフェースを実際に使用してみましょう。
※以下のソースは上で作成したクラスファイルが同じフォルダにあることを前提としています。

【例】
public class Example {

    public static void main(String[] args){

        WithCamera wc = new MobilePhoneA();

        System.out.println("このカメラの画素数は" + wc.getPixel() + "ピクセルです。");

        wc.shootPhotograph();

    }
}

【実行結果】
このカメラの画素数は4000000ピクセルです。
写真を撮ります



インタフェースを実装したクラスのインスタンスは以下のようにインタフェース型の変数へ代入することが可能です。ただし、当然ですがインタフェース型の変数になりますので、参照できるメソッドはインタフェースで定義されたメソッドだけです。

WithCamera wc = new MobilePhoneA();



インタフェースで定義されている次のメソッドはインタフェース型の変数で参照することが出来ます。

System.out.println("このカメラの画素数は" + wc.getPixel() + "ピクセルです。");

wc.shootPhotograph();



キャスト

次のステートメントを見てください。上の記述ではインタフェースで未定義なので無効ですが、下の記述は MobilePhoneA型へキャストしているのでコンパイルエラーにはなりません。オブジェクトの実体も MobilePhoneA型であるため、実行時エラーにもなりません。

System.out.println(wc.getModelName());    // インタフェースで未定義なのでコンパイルエラー

System.out.println(((MobilePhoneA)wc).getModelName());    // キャストすれば実行可能



ページの先頭へ

インタフェースを継承する

インタフェースも通常のクラス同様に定義を継承して新たなインタフェースを作成することが出来ます。前回作成した WithCameraを拡張して、WithMoovieCameraインタフェースを作成します。 インタフェースの継承も通常と同じく「extends」キーワードを使用します。
【例】
interface WithMoovieCamera WithCamera{

    // 動画を撮る
    public void shootAnimation ();

    // 動画の録画可能時間
    public int getMaxRecordTime();

}


カメラ付きを定義したインタフェースを拡張して、動画を撮ることも出来る WithCameraインタフェースを定義してみました。動画を撮るということで、shootAnimation() メソッド、録画可能時間を返す getMaxRecordTime()メソッドがこのインタフェースで定義されています。

当然ですが WithMoovieCameraインタフェースを実装する場合は、これらのメソッドと、基底クラスで定義されているメソッドも実装する必要があります。



ページの先頭へ