【はじめてのJava】superによるメソッド呼び出し1【クラスの継承編】
はじめてのJava
このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。
クラスの継承編
クラスの継承編では、Javaを扱う上で重要な「クラスの継承」について扱っていきます。
前回は変数にsuperを付ける場合について扱いました。
今回はメソッドにsuperを付ける場合について扱います。
目次
thisとsuper
Javaのプログラムを見ているとthisやsuperといったキーワードを見かけることがあります。
thisについてはこちらの記事説明した通り、そのインスタンス自身を表すキーワードです。
同様にsuperについてはこちらの記事説明した通り、親クラスで定義されている要素を示すキーワードです。
superとは
superとは 親クラス で定義されている要素を指し示すキーワードです。
具体例を見てみましょう。
メソッドの呼び出し時にsuperを付ける場合
メソッドの呼び出し時にsuperを付けることで、 親クラスで定義されているメソッドを呼び出せます 。
変数にsuperを付ける場合と似ていますが、こちらは明確に使いどきがあります。
では、superを使ったメソッドの呼び出し方を見てみましょう。
superを使ったメソッドの呼び出し方
superを使ったメソッドの呼び出しは親クラスのメソッドを呼び出す時に使います。 super.メソッド名 とすると親クラスのメソッドを呼び出すことができます。
例えば、以下のように、ParentClassとそれを継承したChildClassがあるとします。
ParentClass
class ParentClass{ void parentMethod(){ System.out.println("defined in ParentClass"); } }
ChildClass
class ChildClass extends ParentClass{ void childMethod(){ System.out.println("defined in ChildClass"); } void printInfo(){ System.out.println("printInfo() in ChildClass"); super.parentMethod(); //親クラスのメソッドを呼んでいる this.childMethod(); //自分自身のメソッドを呼んでいる } }
動作確認クラスと実行結果は以下の通りです。super.parentMethod()によって、ChildClass内から親クラスであるParentClassのparentMethodが呼び出されています。
動作確認用クラス
public class SampleMain{ public static void main(String[] args){ ChildClass child = new ChildClass(); child.printInfo(); } }
実行結果
このようにsuper.メソッド名という呼び出し方をすることで、親クラスのメソッドを呼び出すことができます。
メソッド呼び出し時にsuperを付ける必要性
この例の場合、確かにsuper.メソッド名とすることで、親クラスのメソッドを呼び出すことができています。しかしこの例ではそもそも親クラスと子クラスの中に同じ名前のメソッドが存在しないため、以下のようにsuperなしの形にChildClassを書き換えても親クラスのメソッドを呼び出すことが可能です。
ChildClass(変更後)
class ChildClass extends ParentClass{ void childMethod(){ System.out.println("defined in ChildClass"); } void printInfo(){ System.out.println("printInfo() in ChildClass"); //super.parentMethod(); //親クラスのメソッドを呼んでいる //this.childMethod(); //自分自身のメソッドを呼んでいる //親クラスに同名メソッドがないため、今回は以下でも同じ動作になる parentMethod(); childMethod(); } }
つまり、この例ではわざわざsuperを使って親クラスのメソッドを呼び出せても利点がありません。
これでは変数の時同様、メソッドにもsuperを付ける必要性がありません。では、メソッドにsuperを付ける必要性は本当にないのでしょうか。
ここでのポイントは、「親クラスと子クラスに同名のメソッドが定義されている場合」(つまり、メソッドをオーバーライドした場合)です。
同名のメソッドが定義されている場合
では、ParentClassとChildClassの両方に同名のmethod()メソッドを定義する場合を考えてみましょう。この場合、ChildClassではmethod()メソッドをオーバーライドすることになります。
ソースコードは以下の通りです。
ParentClass
class ParentClass{ void method(){ System.out.println("method in ParentClass"); } }
ChildClass
class ChildClass extends ParentClass{ @Override void method(){ System.out.println("method in ChildClass"); } void printInfo(){ System.out.println("printInfo() in ChildClass"); super.method(); //親クラスのメソッドを呼んでいる this.method(); //自分自身のメソッドを呼んでいる method(); //★ } }
この場合も、親クラスのメソッドはsuper.メソッド名で呼び出せます。同様に、自分自身のメソッドはthis.メソッド名での呼び出しになります。
では、単にmethod()と呼び出している場合(★)はどうでしょうか。
この動作確認用ソースコードと実行結果は以下の通りとなります。実行結果を見ると単にmethod()と呼び出した場合、子クラス側のメソッドが呼ばれていることが分かります。
動作確認用クラス(変更点無し)
public class SampleMain{ public static void main(String[] args){ ChildClass child = new ChildClass(); child.printInfo(); } }
実行結果
この例から、 メソッドをオーバーライドしているときには、親クラス側のメソッドを呼び出すためにはsuper.メソッド名とする必要がある ということがわかります。
変数の時とは異なり、オーバーライドで同名のメソッドを定義する機会は非常に多くあります。そのため親クラスで定義されたメソッドをsuper.メソッド名で呼び出す機会はよくあります。
サンプルプログラム
今回作成したサンプルプログラムは以下の通りです。また、動作確認用のDrive.javaも記載しておきます。
なお、すべて同じディレクトリに保存して動作を確認してください。
ParentClass
class ParentClass{ void method(){ System.out.println("method in ParentClass"); } }
ChildClass
class ChildClass extends ParentClass{ @Override void method(){ System.out.println("method in ChildClass"); } void printInfo(){ System.out.println("printInfo() in ChildClass"); super.method(); //親クラスのメソッドを呼んでいる this.method(); //自分自身のメソッドを呼んでいる method(); //★ } }
動作確認用クラス
public class SampleMain{ public static void main(String[] args){ ChildClass child = new ChildClass(); child.printInfo(); } }
まとめ
・superとは親クラスを指すキーワード
・super.メソッド名とすることで親クラスで定義したメソッドを呼び出すことができる
・子クラスでメソッドのオーバーライドを行っている場合、親クラス側で定義しているメソッドを呼び出す際にはsuper.メソッド名とする
次回
次回もsuperを使ったメソッドの呼び出しを考えます。メンテナンス性も考慮してみたいと思います。
はじめてのJavaシリーズの目次はこちら
クラスの継承編はこちら