#pragma twice

KAB-studio > プログラミング > Javaのオブジェクト指向入門 > 5. 継承で拡張しよう > 5.4 オーバーライドされたメソッドを呼び出すと?
 
前のページへつぎ

5.4 オーバーライドされたメソッドを呼び出すと?

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

 このページで説明する内容は、実は非常に重要な内容です
 結構さらっと説明していますが、ここで説明したことを後で出てくる重要な項目に使うので、しっかり覚えておいてください。

「上書き」の意味

 オーバーライドすることで、された側からした側へ「ひも」が付くということを説明しました。
 このひもがあるおかげで、オーバーライドしたメソッドがされたメソッドを「上書き」することができます。
 この「上書き」にはとても重要な意味があります。本当に「上書き」したようにプログラムが動くのです。

// OneMethodOverridedSubRunner.java

/**
 * 普通のクラス。
 * メソッド2つ持ちます。
 */
class HasTwoMethodSuper
{
    /**
     * 自クラスの名前を出力するメソッドです。
     */
    void printMyName()
    {
        System.out.println( "HasTwoMethodSuper" );
    }

    /**
     * printMyName()メソッドを呼び出すメソッドです。
     */
    void callPrintMyName()
    {
        printMyName();
    }
}

/**
 * HasTwoMethodSuperクラスから継承した、サブクラス。
 * メソッドを追加しています。
 */
class OneMethodOverridedSub extends HasTwoMethodSuper
{
    /**
     * 自クラスの名前を出力するメソッドです。
     * オーバーライドしています。
     */
    void printMyName()
    {
        System.out.println( "OneMethodOverridedSub" );
    }

    // callPrintMyName()メソッドはオーバーライドしません。
}

/**
 * 実行用クラス。このクラスを実行してください。
 */
class OneMethodOverridedSubRunner
{
    public static void main( String[] args )
    {
        // インスタンスを1つ作り数値を入れます。
        OneMethodOverridedSub ref = new OneMethodOverridedSub();

        // callPrintMyName()メソッドを呼び出します。
        ref.callPrintMyName();
        // 出力結果:
        // OneMethodOverridedSub
    }
}
// OneMethodOverridedSubRunner.java
/**
 * 普通のクラス。
 * メソッド2つ持ちます。
 */
class HasTwoMethodSuper
{
	/**
	 * 自クラスの名前を出力するメソッドです。
	 */
	void printMyName()
	{
		System.out.println( "HasTwoMethodSuper" );
	}
	/**
	 * printMyName()メソッドを呼び出すメソッドです。
	 */
	void callPrintMyName()
	{
		printMyName();
	}
}
/**
 * HasTwoMethodSuperクラスから継承した、サブクラス。
 * メソッドを追加しています。
 */
class OneMethodOverridedSub extends HasTwoMethodSuper
{
	/**
	 * 自クラスの名前を出力するメソッドです。
	 * オーバーライドしています。
	 */
	void printMyName()
	{
		System.out.println( "OneMethodOverridedSub" );
	}
	// callPrintMyName()メソッドはオーバーライドしません。
}
/**
 * 実行用クラス。このクラスを実行してください。
 */
class OneMethodOverridedSubRunner
{
	public static void main( String[] args )
	{
		// インスタンスを1つ作り数値を入れます。
		OneMethodOverridedSub ref = new OneMethodOverridedSub();
		// callPrintMyName()メソッドを呼び出します。
		ref.callPrintMyName();
		// 出力結果:
		// OneMethodOverridedSub
	}
}

 まずHasTwoMethodSuperクラスを用意します。

/**
 * 普通のクラス。
 * メソッド2つ持ちます。
 */
class HasTwoMethodSuper
{
    /**
     * 自クラスの名前を出力するメソッドです。
     */
    void printMyName()
    {
        System.out.println( "HasTwoMethodSuper" );
    }

    /**
     * printMyName()メソッドを呼び出すメソッドです。
     */
    void callPrintMyName()
    {
        printMyName();
    }
}
/**
 * 普通のクラス。
 * メソッド2つ持ちます。
 */
class HasTwoMethodSuper
{
	/**
	 * 自クラスの名前を出力するメソッドです。
	 */
	void printMyName()
	{
		System.out.println( "HasTwoMethodSuper" );
	}
	/**
	 * printMyName()メソッドを呼び出すメソッドです。
	 */
	void callPrintMyName()
	{
		printMyName();
	}
}

 このクラスは2つのメソッドを持ちます。
 printMyName()メソッドは、前ページの例と同じように、クラス名を出力します。
 callPrintMyName()メソッドは、そのprintMyName()メソッドを呼び出します。

 このHasTwoMethodSuperクラスのサブクラス、OneMethodOverridedSubクラスを作ります。

/**
 * HasTwoMethodSuperクラスから継承した、サブクラス。
 * メソッドを追加しています。
 */
class OneMethodOverridedSub extends HasTwoMethodSuper
{
    /**
     * 自クラスの名前を出力するメソッドです。
     * オーバーライドしています。
     */
    void printMyName()
    {
        System.out.println( "OneMethodOverridedSub" );
    }

    // callPrintMyName()メソッドはオーバーライドしません。
}
/**
 * HasTwoMethodSuperクラスから継承した、サブクラス。
 * メソッドを追加しています。
 */
class OneMethodOverridedSub extends HasTwoMethodSuper
{
	/**
	 * 自クラスの名前を出力するメソッドです。
	 * オーバーライドしています。
	 */
	void printMyName()
	{
		System.out.println( "OneMethodOverridedSub" );
	}
	// callPrintMyName()メソッドはオーバーライドしません。
}

 このクラスではprintMyName()メソッドを持っています。
 このprintMyName()メソッドは、スーパークラスのprintMyName()メソッドと同じ名前・引数なので、printMyName()メソッドをオーバーライドしていることになります。
 また、callPrintMyName()メソッドはオーバーライドしていません。オーバーライドしているのはprintMyName()メソッドだけという点に注意してください。

 そしていつものようにインスタンスを作ります。

        // インスタンスを1つ作ります。
        OneMethodOverridedSub ref = new OneMethodOverridedSub();
		// インスタンスを1つ作ります。
		OneMethodOverridedSub ref = new OneMethodOverridedSub();

 printMyName()メソッドはオーバーライドしているので、された側からした側へひもが付きます。

 さてここで、callPrintMyName()メソッドを呼び出してみます。
 callPrintMyName()メソッドはスーパークラスにしかないメソッドですから、そのまま普通にcallPrintMyName()メソッドが呼び出されます。
 callPrintMyName()メソッドの中では、printMyName()メソッドを呼び出します。
 この時呼び出されるprintMyName()メソッドは、オーバーライドした方のメソッドが呼び出されます
 つまり、サブクラスのprintMyName()メソッドが呼び出されるということです。

        // callPrintMyName()メソッドを呼び出します。
        ref.callPrintMyName();
        // 出力結果:
        // OneMethodOverridedSub
		// callPrintMyName()メソッドを呼び出します。
		ref.callPrintMyName();
		// 出力結果:
		// OneMethodOverridedSub

 このように「OneMethodOverridedSub」が出力されていますから、OneMethodOverridedSubクラスのprintMyName()メソッドが呼び出されているわけです。
 これがつまり、「オーバーライドはメソッドを上書きする」ということです。

 同じスーパークラス内であれば、スーパークラスにあるメソッドが呼ばれそうですが、そのメソッドがオーバーライドされていた場合には、サブクラスにあるオーバーライドしたメソッドが呼び出されるわけです。
 このように、オーバーライドは単に「サブクラスに同名クラスを作る」というだけではなく、元のメソッドを「上書き」するという機能も持っているわけです。

これはとっても重要!

 繰り返しになりますが、この「上書きする」という機能はとっても重要です。
 この考え方が後の「ポリモーフィズム」で重要になりますので、必ず覚えておいてください。

5.4 オーバーライドされたメソッドを呼び出すと?
このページは、Java言語を用いたオブジェクト指向プログラミングのチュートリアル解説を行う「Javaのオブジェクト指向入門」の一ページです。
詳しい説明は「Javaのオブジェクト指向入門」目次をご覧ください。