2018年05月10日

師匠のJava道場~第9回・クラスを継承するのじゃ!

師匠T:さて、今回はクラスについての話第二弾、継承について話すとするぞ。準備はよいか?

弟子D:はい、師匠! でも、クラスについての話であれば、前回にすればよかったような。

師匠T:筆者が勉強したのは、クラス→キャスト→継承の順番だったのじゃ、仕方なかろう。

弟子D:わかったような、わからんような。

師匠T:無理やりわかれ。では始めるぞ!

▽継承とはなんぞや?▽

師匠T:例えば、ゲームを作るときのことを考えてみよ。自機や敵に共通して、移動の処理があるが、二つのクラスそれぞれに移動の処理を書いていたら大変じゃの。

弟子D:そういえばそうですね。

師匠T:そんなとき、移動の処理を持つ共通のクラスを作り、それから自機や敵のクラスを作れば、移動させるときには、その処理を呼び出せばいいので楽ではないか?

弟子D:おぉ、それは確かにっ。

師匠T:これが継承の利点じゃ。そして話が前後してしまったが、継承とは、あるクラスを基にして別なクラスを作ることを言う。

弟子D:ガンダムで例えるなら、ザクを基にして、ザクキャノンや高機動型ザク、サイコミュ高機動試験型ザクを作るようなものですね!

師匠T:なぜおぬしがザクキャノンや高機動型ザクはまだしも、ビショップ(=サイコミュ高機動試験型ザク)のような、マニアックなMSのことを知っているかは置いといて、見事な例えじゃな、まさにその通りじゃ。

弟子D:師匠がビショップの名前を知っているのも十分謎ですが……。

師匠T:気にするな。さて、次は継承のやり方について説明することにするぞ!

▽継承のやり方じゃ!▽

師匠T:継承のやり方じゃが、とても簡単。クラス名の宣言のあとに、こうつければいいだけじゃ。

----------
extends [スーパークラス名]

例:
public ZakuCannon extends Zaku
----------

師匠T:前々回説明した通り、スーパークラスとは、あるクラスの基になったクラス、サブクラスとは、あるクラスを基にして作られたクラスを言う。例えば、ZakuクラスからZakuCannonクラスを作った場合、ZakuクラスはZakuCannonのスーパークラス、ZakuCannonクラスは、Zakuクラスのサブクラス、となるわけじゃ。

弟子D:ふむふむ。

師匠T:さてさて。継承してクラスを作った場合、スーパークラスのメソッドやフィールドは、private宣言されているものを除いて、全て継承される。例えば、前々回作ったZakuクラスからZakuCannonクラスを作った場合、Zakuクラスに備え付けられていたfireメソッドも、ZakuCannonクラスは自動的に持つことになるのじゃ。

弟子D:なるほど。コンストラクタはどうなのでしょう?

師匠T:残念ながら、コンストラクタは継承されぬ。じゃが、スーパークラスのコンストラクタを利用する方法はあるので安心するがよい。

▽Objectクラスじゃ!▽

師匠T:さて、次はObjectクラスについて語るとしようぞ。

弟子D:確か前回も出てきましたね。あらゆるクラスの親になるクラスでしたっけ。

師匠T:うむ、そのとおりじゃ。よく覚えておったの。このObjectクラスは、継承について大きな意味を持つ。

弟子D:それはどのような?

師匠T:うむ。継承させずにクラスを作るとき、当然ながら、extendsはつけぬな?

弟子D:はい。

師匠T:そのような場合、Javaは内部で自動的に、『extends Object』と補完するようになっておるのじゃ。このことについて、わしら開発者側は意識することはないがの。

弟子D:なるほど、よくわかりました!

▽継承のさいの注意点じゃ!▽

師匠T:さて、続いては、継承のさいに気を付けることについて語るとするぞ。まず一つは、継承を行うさい、スーパークラスにできるのは一つだけ。二つのクラスから継承して、サブクラスを作ることはできぬのじゃ。
例えるなら、Zakuクラスと、Goufクラスから継承して、ZakuGoufクラスを作る、なんてことはできぬのじゃ。

弟子D:それでは、そのようなものを作りたいときはどうすれば?

師匠T:うむ。そのような場合には、インターフェースというものを使う。じゃが、これの説明はあとに回すとしよう。

弟子D:はい。それで、今一つは?

師匠T:うむ。これが、難しくも重大なポイントじゃ。『[引数を持たないコンストラクタ]を持たないスーパークラスを継承するさいには、注意が必要』ということじゃ。

弟子D:それはどのようなことなのでしょう?

師匠T:うむ。そのようなクラスを継承するさい、コンストラクタを作らずに継承した場合、Javaは、勝手に『引数を持たないコンストラクタ』を補完してしまう。じゃが、スーパークラスはそのコンストラクタを持たぬゆえ、ビルドエラーになってしまうのじゃ。

弟子D:むむむ、なんか難しいですね。

師匠T:まぁ、難しければ、『[引数を持たないコンストラクタ]を持たないクラスを継承する場合、サブクラスのほうで、そんなコンストラクタを作ること』と覚えておけば問題はなかろう。

弟子D:ううう、わかりました、師匠。

▽スーパークラスの変数への紐づけじゃ!▽

師匠T:さて、この話をするさいに、一つ前提として覚えておくことがある。オブジェクト型の変数というものは、String型と同じように、オブジェクト(=インスタンス)へのリンクが張られた存在、ということじゃ。

弟子D:例えば、Zakuクラスの変数oZakuは、中に本当にZakuクラスのインスタンスが入っているわけではなく、インスタンスは別の場所にあり、変数からそのインスタンスへのリンクが張られている、ということですか?

師匠T:うむ、そういうことじゃ。さて、例えば、ある変数に、それと同じクラスのインスタンスをリンクすることができる……これは当然じゃな?

----------
※ZakuCannonは、Zakuのサブクラスです。
ZakuCannon CharsZaku = new ZakuCannon(~);
----------

弟子D:はい、そうですね。

師匠T:じゃが、ある変数に、そのクラスのサブクラスのインスタンスをリンクさせる、ということもできるのじゃ!

----------
Zaku GarmasZaku = new ZakuCannon(~);
----------

弟子D:な、なんと! それはすごいです、師匠!

師匠T:うむ、じゃが、この使い方をした場合、いくつか制限がある。まず一つ、作られるインスタンスは、作る際に指定したクラスのもので、リンク先の変数のクラスには影響されない、ということじゃ。つまり、上の例でいえば、作られるのはZakuCannonクラスで、Zakuクラスにはならん、ということじゃな。

弟子D:ちょっと難しいですけど、考えれば当然の話ですね。

師匠T:そして二つ目。リンク先の変数のクラスにないメソッドやフィールドは使うことはできない、というものじゃ。例えば、ZakuCannonクラスにLongShotメソッドというメソッドがあっても、この場合は使うことができぬ、ということじゃ。

弟子D:ふむふむ。

師匠T:そして最後。両方のクラスに同じメソッドがあった場合、インスタンスのクラス側のメソッドが実行される、ということじゃ。

弟子D:なるほど!

▽コンストラクタの補完その他じゃ!▽

師匠T:では、今回の講座のラストじゃ。クラスを作る場合、コンストラクタを省略した場合は、デフォルトコンストラクタが補完される。

弟子D:師匠、デフォルトコンストラクタとはいかに?

師匠T:デフォルトコンストラクタとは、コンストラクタがない場合、Javaが自動的に作ってくれるコンストラクタのことじゃ。次のような構造となっている。

----------
[クラス名]()
{

}

例:
Zaku()
{

}
----------

弟子D:引数を何も持たず、中身もないんですね。なぜこのようなものを?

師匠T:うむ。それは、コンストラクタを作った場合、Javaが自動的に、super()という命令を補完して、スーパークラスのコンストラクタを呼び出すようにしてくれるからじゃ。(コンストラクタを作らず、Javaがデフォルトコンストラクタを作った場合も含む)じゃが、元々スーパークラスにコンストラクタがないと、困ったことになる。そこで、コンストラクタを作らなかった場合、自動的にJavaがデフォルトコンストラクタを用意してくれる、というわけなのじゃ。

弟子D:なるほど。

師匠T:なお、super()の記述は、Javaの補完に任せず、自分で書くこともできる。その場合、コンストラクタの最初の行に書く必要がある。よいかな?

弟子D:はい、師匠!

師匠T:うむ、ではいよいよ最後じゃ。先ほど話した、スーパークラスのメソッドやフィールドを使いたい場合。これにもsuperを使う。その方法はこうじゃ。

----------
super.[メソッド名orフィールド名]

例:
super.x = 5;
super.fire();
----------

弟子D:superのあとに、ピリオドで区切って、メソッド名やフィールド名を書けばいいんですね。わかりました!

師匠T:うむ。さて、次回は、抽象クラスについて語ることにするぞ。予習、復習を欠かしてはならぬ!

※次回の更新は、5月14日、『師匠TのチャレンジARSゲーム!』の予定です。お楽しみに!
posted by 裏編 at 07:31| 師匠のJava道場 | 更新情報をチェックする