このページで説明する内容は、実は非常に重要な内容です。
結構さらっと説明していますが、ここで説明したことを後で出てくる重要な項目に使うので、しっかり覚えておいてください。
「上書き」の意味
オーバーライドすることで、された側からした側へ「ひも」が付くということを説明しました。
このひもがあるおかげで、オーバーライドしたメソッドがされたメソッドを「上書き」することができます。
この「上書き」にはとても重要な意味があります。本当に「上書き」したようにプログラムが動くのです。
/**
* 普通のクラス。
* メソッド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()メソッドだけという点に注意してください。
そしていつものようにインスタンスを作ります。
OneMethodOverridedSub ref = new OneMethodOverridedSub();
// インスタンスを1つ作ります。 OneMethodOverridedSub ref = new OneMethodOverridedSub();
printMyName()メソッドはオーバーライドしているので、された側からした側へひもが付きます。
さてここで、callPrintMyName()メソッドを呼び出してみます。
callPrintMyName()メソッドはスーパークラスにしかないメソッドですから、そのまま普通にcallPrintMyName()メソッドが呼び出されます。
callPrintMyName()メソッドの中では、printMyName()メソッドを呼び出します。
この時呼び出されるprintMyName()メソッドは、オーバーライドした方のメソッドが呼び出されます。
つまり、サブクラスのprintMyName()メソッドが呼び出されるということです。
ref.callPrintMyName();
// 出力結果:
// OneMethodOverridedSub
// callPrintMyName()メソッドを呼び出します。 ref.callPrintMyName(); // 出力結果: // OneMethodOverridedSub
このように「OneMethodOverridedSub」が出力されていますから、OneMethodOverridedSubクラスのprintMyName()メソッドが呼び出されているわけです。
これがつまり、「オーバーライドはメソッドを上書きする」ということです。
同じスーパークラス内であれば、スーパークラスにあるメソッドが呼ばれそうですが、そのメソッドがオーバーライドされていた場合には、サブクラスにあるオーバーライドしたメソッドが呼び出されるわけです。
このように、オーバーライドは単に「サブクラスに同名クラスを作る」というだけではなく、元のメソッドを「上書き」するという機能も持っているわけです。
これはとっても重要!
繰り返しになりますが、この「上書きする」という機能はとっても重要です。
この考え方が後の「ポリモーフィズム」で重要になりますので、必ず覚えておいてください。