#pragma twice

KAB-studio > プログラミング > Javaのオブジェクト指向入門 > 7. ポリモーフィズム!! > 7.1 アップキャスト
 
前のページへつぎ

7.1 アップキャスト

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

 この章では、オブジェクト指向で一番「面白い」であろう「ポリモーフィズム」というものを紹介します。
 かなり突拍子もない不思議な機能なのですが、オブジェクト指向では必須の機能です。最初は戸惑うかもしれませんが、恐れず挑戦してみましょう。

「参照型変数」の型を変える

 これまでずっと「参照型変数の型は、インスタンスの型と同じにする」のだと説明してきました。
 たとえば、「5.2 継承で機能を加える」で紹介したAddedSubクラスを例に、インスタンスを作成している箇所を見てみると、両方とも同じ型になっています。

        AddedSub ref = new AddedSub();
		AddedSub ref = new AddedSub();

 「参照型変数refの型」と「newで指定する型」が両方ともAddedSubになっています。
 「AddedSubクラスのインスタンス」に結びついている参照の型は「AddedSubクラスの参照型」となるので、それを「AddedSubクラスの参照型変数に入れる」のは当然と言えます。

 ところが実は、参照型変数は、インスタンス作成時の型だけではなく、そのスーパークラスの型で作っても、参照を受け取ることができます。
 たとえば上記の例では、ref変数は「AddedSubクラス」だけでなく、「NormalSuperクラス」で作ってもいいんです。

 というわけで、例によってサンプルプログラムで確認してみましょう。

// AddedSub2Runner.java

/**
 * 普通のクラス。
 * (NormalSuperクラスと全く同じクラスです)
 */
class NormalSuper2
{
    // int型変数のdataフィールドです。
    int data;

    /**
     * フィールドを出力するメソッドです。
     */
    void printData()
    {
        System.out.println( data );
    }
}

/**
 * NormalSuper2クラスから継承した、サブクラス。
 * フィールドとメソッドを追加しています。
 * (AddedSubクラスと全く同じクラスです)
 */
class AddedSub2 extends NormalSuper2
{
    // int型変数のdataSubフィールドです。
    int dataSub;

    /**
     * フィールドを出力するメソッドです。
     */
    void printDataSub()
    {
        // このクラスで追加したフィールドを出力。
        System.out.println( dataSub );

        // ついでにスーパークラスのフィールドも出力。
        System.out.println( data );
    }
}

/**
 * 実行用クラス。このクラスを実行してください。
 */
class AddedSub2Runner
{
    public static void main( String[] args )
    {
        // インスタンスを1つ作り数値を入れます。
        // ただし、参照型変数はスーパークラスの型にします。
        NormalSuper2 ref = new AddedSub2();

        // スーパークラスのフィールドに値を入れて出力します。
        ref.data = 100;
        ref.printData();
        // 出力結果:
        // 100
    }
}
// AddedSub2Runner.java
/**
 * 普通のクラス。
 * (NormalSuperクラスと全く同じクラスです)
 */
class NormalSuper2
{
	// int型変数のdataフィールドです。
	int data;
	/**
	 * フィールドを出力するメソッドです。
	 */
	void printData()
	{
		System.out.println( data );
	}
}
/**
 * NormalSuper2クラスから継承した、サブクラス。
 * フィールドとメソッドを追加しています。
 * (AddedSubクラスと全く同じクラスです)
 */
class AddedSub2 extends NormalSuper2
{
	// int型変数のdataSubフィールドです。
	int dataSub;
	/**
	 * フィールドを出力するメソッドです。
	 */
	void printDataSub()
	{
		// このクラスで追加したフィールドを出力。
		System.out.println( dataSub );
		// ついでにスーパークラスのフィールドも出力。
		System.out.println( data );
	}
}
/**
 * 実行用クラス。このクラスを実行してください。
 */
class AddedSub2Runner
{
	public static void main( String[] args )
	{
		// インスタンスを1つ作り数値を入れます。
		// ただし、参照型変数はスーパークラスの型にします。
		NormalSuper2 ref = new AddedSub2();
		// スーパークラスのフィールドに値を入れて出力します。
		ref.data = 100;
		ref.printData();
		// 出力結果:
		// 100
	}
}

 NormalSuper2クラスとAddedSub2クラスは「5.2 継承で機能を加える」とほぼ同じクラスです。クラス名が違うだけで、フィールド・メソッドは全く同じです。
 継承関係も同じです。NormalSuper2クラスがスーパークラス、AddedSub2クラスがサブクラスになります。

 さて、これまでの例では、AddedSub2クラスのインスタンスに結びつく参照を、AddedSub2クラスの参照型変数に入れていました。
 でも、今回はAddedSub2クラスの参照型変数ではなく、そのスーパークラスの、NormalSuper2クラスの参照型変数に入れています。

        // インスタンスを1つ作り数値を入れます。
        // ただし、参照型変数はスーパークラスの型にします。
        NormalSuper2 ref = new AddedSub2();
		// インスタンスを1つ作り数値を入れます。
		// ただし、参照型変数はスーパークラスの型にします。
		NormalSuper2 ref = new AddedSub2();

 ref変数は、AddedSub2クラスの参照型ではなく、NormalSuper2クラスの参照型です。
 つまり、インスタンスの型ではなく、そのスーパークラスの型ということです。

 このような、「スーパークラスの参照型へ、サブクラスの参照を入れる」ことを「アップキャスト」と言います。
 「AddedSub2クラスの参照型」から「NormalSuper2クラスの参照型」へ「型変換」されるので、キャストの一種になります。ただし、intからlongへのキャストが何もしなくてもできるように、アップキャストも「特になにもしなくても自動的に行われる型変換」です。

 このアップキャストだけ見ると「なんのためにこんな機能が?」と思われるかもしれません。
 でもこの機能が「ポリモーフィズム」という機能に大きく関わってくるのです。

7.1 アップキャスト
このページは、Java言語を用いたオブジェクト指向プログラミングのチュートリアル解説を行う「Javaのオブジェクト指向入門」の一ページです。
詳しい説明は「Javaのオブジェクト指向入門」目次をご覧ください。