#pragma twice

KAB-studio > プログラミング > Javaのオブジェクト指向入門 > 10. インタフェースという「クラスじゃないもの」 > 10.1 インタフェースという「抽象クラスっぽいもの」
 
前のページへつぎ

10.1 インタフェースという「抽象クラスっぽいもの」

del.icio.us 登録する はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数 livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数 Yahoo!ブックマーク 詳細を表示 users RSSに登録
更新日: 2008/04/28
動作確認環境:Windows XP Professional SP2, Java SE 5

 最後に紹介するのは「インタフェース」です。
 このインタフェース、Javaの中で最も「なんのためにあるの?」と思われている機能です。
 でもこのインタフェースが分かればオブジェクト指向に一気に近づきます!
 ラストスパート、がんばりましょう!

インタフェースを使ってみる

 前章で「抽象クラス」を紹介しました。
 これを強力にした「インタフェース」というものを今回使ってみましょう。

// ImplementedRunner.java

/**
 * インタフェース。
 */
interface PrintInterface
{
    /**
     * 抽象メソッド。
     */
    void printMyName();
}

/**
 * PrintInterfaceインタフェースの実装クラス。
 */
class Implemented implements PrintInterface
{
    /**
     * 抽象メソッドをオーバーライドします。
     */
    public void printMyName()
    {
        System.out.println( "Implemented" );
    }
}

/**
 * 実行用クラス。このクラスを実行してください。
 */
class ImplementedRunner
{
    public static void main( String[] args )
    {
        // Implementedクラスのインスタンスを1つ作ります。
        // 参照型変数はPrintInterfaceクラスです。
        PrintInterface ref = new Implemented();

        // 実装したメソッドを呼び出します。
        ref.printMyName();
        // 実行結果:
        // Implemented
    }
}
// ImplementedRunner.java
/**
 * インタフェース。
 */
interface PrintInterface
{
	/**
	 * 抽象メソッド。
	 */
	void printMyName();
}
/**
 * PrintInterfaceインタフェースの実装クラス。
 */
class Implemented implements PrintInterface
{
	/**
	 * 抽象メソッドをオーバーライドします。
	 */
	public void printMyName()
	{
		System.out.println( "Implemented" );
	}
}
/**
 * 実行用クラス。このクラスを実行してください。
 */
class ImplementedRunner
{
	public static void main( String[] args )
	{
		// Implementedクラスのインスタンスを1つ作ります。
		// 参照型変数はPrintInterfaceクラスです。
		PrintInterface ref = new Implemented();
		// 実装したメソッドを呼び出します。
		ref.printMyName();
		// 実行結果:
		// Implemented
	}
}

 まず最初に出てくるPrintInterfaceが「インタフェース」というものです。

/**
 * インタフェース。
 */
interface PrintInterface
{
    /**
     * 抽象メソッド。
     */
    void printMyName();
}
/**
 * インタフェース。
 */
interface PrintInterface
{
	/**
	 * 抽象メソッド。
	 */
	void printMyName();
}

 インタフェースはクラスに似ていますが、ちょっと違います。
 まず「class」ではなく「interface」を付けます。「interface 名前 { ~ }」とすることで、インタフェースを作ることができます。
 中カッコの中身には、普通のメソッドは書くことができません
 この例のように、抽象メソッドは書くことができます。その際、抽象クラスと違って「abstract」を付ける必要はありません。普通にメソッドを書き、「{~}」の代わりに「;」を書けばそれが抽象メソッドになります。
 また、インタフェースはフィールドを持つことができません。インタフェースの中に書けるのは「抽象メソッド」と「public static finalなフィールド」のみです。
 まぁインタフェースには抽象メソッドしか書けないと憶えましょう。

 インタフェースは抽象クラスのようなものなので、使う時にはサブクラスのようなものを作る必要があります。
 この例ではImplementedクラスがそれに当たります。

/**
 * PrintInterfaceインタフェースの実装クラス。
 */
class Implemented implements PrintInterface
{
    /**
     * 抽象メソッドをオーバーライドします。
     */
    public void printMyName()
    {
        System.out.println( "Implemented" );
    }
}
/**
 * PrintInterfaceインタフェースの実装クラス。
 */
class Implemented implements PrintInterface
{
	/**
	 * 抽象メソッドをオーバーライドします。
	 */
	public void printMyName()
	{
		System.out.println( "Implemented" );
	}
}

 こちらは普通のクラスです。ただ、やっぱりちょっとだけ違います。
 まず、「extends」の代わりに「implements」を使います。これまで継承は「class A extends B」としていましたが、インタフェースからの場合は「class A implements B」と書きます。

 また、用語もちょっと違います。「class A extends B」のAは「スーパークラス」、Bは「サブクラス」でした。ところがインタフェースの場合、「class A implements B」のAは「実装クラス」、Bは「インタフェース」と呼びます。
 つまり、Implementedクラスは実装クラスです。PrintInterfaceインタフェースから見て、Implementedクラスは実装クラスなのです。
 へんてこな用語が出てきて戸惑うかもしれませんが、この用語は大事なので憶えてください。

 オーバーライドの仕方は抽象クラスの時の同じです。抽象メソッドと同じ名前のメソッドを作ればOKです。
 ただ、また用語が違います。インタフェースの抽象メソッドは、「サブクラスでオーバーライドする」ではなく「実装クラスで実装する」と言います。「オーバーライド」じゃなく「実装」、です。
 あと、インタフェースの抽象メソッドは自動的にpublicなメソッドになるので、実装したメソッドにはpublicを付ける必要がありますのでこの点も注意しておいてください。

 今紹介したPrintInterfaceインタフェースとImplementedクラスは、「9.1 abstractクラスとabstractメソッド」のAbstractSuperクラスとConcreteSubクラスの関係と同じです。
 インタフェースは、機能的には抽象クラスの強化版、抽象メソッドしか書けず普通のフィールドやメソッドは持てないクラス、と考えると分かりやすいでしょう。

 使う時は抽象クラスの時と同じです。

        // Implementedクラスのインスタンスを1つ作ります。
        // 参照型変数はPrintInterfaceクラスです。
        PrintInterface ref = new Implemented();
		// Implementedクラスのインスタンスを1つ作ります。
		// 参照型変数はPrintInterfaceクラスです。
		PrintInterface ref = new Implemented();

 Implementedクラスのインスタンスを作り、その参照をPrintInterfaceインタフェースの参照型変数で受け取ります。

 そして、インタフェースの抽象メソッドを通して、実装クラスで実装しているメソッドを呼び出すことができます。

        // 実装したメソッドを呼び出します。
        ref.printMyName();
        // 実行結果:
        // Implemented
		// 実装したメソッドを呼び出します。
		ref.printMyName();
		// 実行結果:
		// Implemented

 抽象メソッドのprintMyName()メソッドを呼び出すと、そのメソッドを実装している「ImplementedクラスのprintMyName()メソッド」が呼び出されます。
 このあたりの使用感は抽象メソッドと同じですし、ポリモーフィズムが行われていると素直に考えるといいでしょう。

 このように、インタフェースは抽象クラスに非常によく似ています
 特に機能的には「抽象クラスの強化版」と考えて問題ありません。
 でも実は全然別物だったりします。その違いをこれからゆっくり見ていきましょう。

10.1 インタフェースという「抽象クラスっぽいもの」
このページは、Java言語を用いたオブジェクト指向プログラミングのチュートリアル解説を行う「Javaのオブジェクト指向入門」の一ページです。
詳しい説明は「Javaのオブジェクト指向入門」目次をご覧ください。