2018年06月07日

師匠のJava道場~第10回・抽象クラスを使うのじゃ!

弟子D:ど、どうなさったのですか、師匠? 何か黒いオーラが。

師匠T:いや、この間散歩しておったら、カップルがいっぱいな……いやなんでもない。気にするな。

弟子D:は、はぁ……(触らぬ神に……)

師匠T:さて、今回は抽象クラスについて説明する。覚悟はよいか?

弟子D:は、はい……。

▽抽象クラスとは?▽

弟子D:師匠、いきなりですが、抽象クラスとはなんぞや。

師匠T:うむ。抽象クラスとは、普通のクラスとは少し違っておって、継承されることを前提としたクラスじゃ。
 これには、次のような特徴があるぞ。

弟子D:ふむ。

師匠T:まず一つ。抽象クラスはインスタンスを作ることができない。

弟子D:つまり、例えば、Zakuクラスが抽象クラスだとして、そこからインスタンスのoZakuを作ることはできない、ということてすね? こんな風に。

----------
Zaku oZaku = new Zaku();
----------

師匠T:うむ、その通りじゃ。ただし、継承はできることを忘れてはならぬぞ。また二つ目の特徴として、抽象クラスは特別に、処理内容の中身を持たぬ、抽象なメソッド……ずばり抽象メソッドを持つことができる。
もちのろん、普通のメソッドを持つこともできるぞ。

弟子D:なるほど。でも、処理内容のないメソッドを用意して何になるんです?

師匠T:うむ、よい質問じゃの。例えば、複数のクラスの中で、ほぼ同じメソッドがあるとするじゃろ?

弟子D:はい。

師匠T:そうした場合、各クラスで別々のメソッド名にされては、管理が色々と困難になる。そこで、抽象クラス側で、そうしたメソッドを用意しておき、その処理は、この用意されたメソッドに書いてもらえばいい、というわけじゃ。
例えば、ZakuクラスもGoufクラスも、マシンガンを撃つ処理がある場合、スーパークラス側にMachineGunメソッドを用意しておき、どちらのクラスも、これを使ってもらえばいいというわけじゃな。

弟子D:なるほど!

師匠T:では次はいよいよ、抽象クラスの作り方、などについて説明するぞ!

▽抽象クラス、抽象メソッドを作るには?▽

師匠T:まずは、抽象クラスの作り方について説明していくとしよう。といっても簡単じゃ。クラス名の前に、abstractと描けばよい。

----------
例:abstract class Mobile Suits()
----------

弟子D:ふむふむ。

師匠T:そして、抽象メソッドの作り方じゃ。これもまた簡単で、メソッド名の前に、同じようにabstractをつければよい。

弟子D:ふむふむ。あ、publicとかprivateとか、型名とかの前と後、どちらに書けばいいんですか?

師匠T:おぉ、それがあったの。よくぞ気が付いた。

弟子D:忘れるなんて、師匠ももうと……。

師匠T:何か言ったか?

弟子D:いえ、なんでもありません……。

師匠T:ごほん。abstractは、それらの前に書けばよいのじゃ。この通り。

----------
例:abstract public void MachineGun();
----------

師匠T:この例の通り、抽象メソッドには、波かっこ({})もその処理も、何も書いてはならぬ。必ず、()の後、;で〆るのじゃ。

弟子D:ふむふむ。

師匠T:そして、ポイントをもう一つ。抽象メソッドを持たせれば、そのクラスは必ず抽象クラスになる。ゆえに……。

弟子D:そのクラスにも、abstractをつけなきゃならない、ということですね。

師匠T:さて。こうして作った抽象クラスを継承した場合、そのサブクラスは、次のいずれかになる。

(1) 抽象メソッドを全て実装(メソッドの処理内容を全て書く)した場合、通常のクラスになる。
(2) 抽象メソッドが一つでも実装されなかった場合、そのクラスも抽象クラスになる。

師匠T:このため、(2)に該当するクラスにも、abstractをつけなくてはならぬ。注意せよ。

弟子D:はい、師匠!

師匠T:なお、継承したサブクラスで、その抽象メソッドを使う場合は、いつも通りにそのまま使えばよい。

----------
※抽象クラス側
abstract public int Shot();


※サブクラス側
public int Shot() {

}
----------

▽参照型変数についてじゃ!▽

師匠T:このことについて話す前に、一つ教えておくべきことがある。前回、オブジェクト型の変数は、実際に中に何か入っているわけではなく、変数から、オブジェクトにリンクが張られている、と話したな?

弟子D:はい。

師匠T:このような変数を、『参照型変数』ともいう。覚えておくように。

弟子D:わかりました!

師匠T:うむ。さて、先ほど話した通り、抽象クラスからはインスタンスを作ることができぬ。じゃが、今話した参照型変数にすることはできるのじゃ。

----------
※MobileSuitsクラスは抽象クラスです。
Zaku oZaku = new MobileSuits(); はNG
MobileSuits oMS = new Zaku(); はOK
----------

弟子D:ふむふむ。

師匠T:これは、後に説明する多態性について重要なポイントなので、心の片隅にでも覚えておくがよい。

弟子D:はい、師匠!

▽thisについてなのじゃ!▽

師匠T:さて。それでは次は、抽象メソッドの実装についてじゃ。スーパークラスで宣言されたフィールド(変数)を、サブクラス側で利用したい場合は、次のように書く。

----------
this.〇〇〇
例:this.sisyo
----------

弟子D:なるほど! ところで、サブクラスってなんでしたっけ?

師匠T:はぁっ!!(飛び蹴り)

▽オーバーライドについてなのじゃ!▽

師匠T:さて、次は@overrideについてじゃ。これは、次の二つの使用法で使われる。

(1) 抽象メソッドを実装する
(2) 既にあるメソッドの内容を上書きする
(3) インターフェイスの抽象メソッドを実装する

師匠T:(3)については、後の講座で説明するぞ。さて、(1)については既に話したの?

弟子D:はい。処理内容が何もないメソッドの処理を実際に書く……でいいんでしたっけ?

師匠T:うむ、そのようなものと考えればよかろう。そして、(2)についてじゃが、例えば、RPGにおいて、戦闘終了後の処理で、既存のシステムでは経験値とお金だけが入るのだが、今度作るゲームでは、特別なポイントを増やしたい、という場合があったりするじゃろ?

弟子D:はい。

師匠T:そのような場合、その既存の処理を残し、その処理の後、特別なポイントを増やす、という手法が使われることがある。場合によっては、その処理を丸々書き換えることもあるがの。
このように、スーパークラスのメソッドを、サブクラス側で書き換えることを、オーバーライドというのだ。

弟子D:なるほど。

師匠T:さて、そのような場合に使われる@overrideじゃが、使い方はそう難しいことではない。対象となるメソッドのすぐ上に、これを書けばいいだけじゃ。

----------
@override
public void MachineGun()
{

----------

弟子D:なるほど、わかりました。師匠!

▽多態性についてなのじゃ!▽

師匠T:さて。では最後に、先ほど話した、多態性について話すとしようぞ。多態性とは一言で言ってしまえば、同じメソッドでも、クラスによって実際の処理が異なることを言う。

弟子D:???

師匠T:例えばじゃ。例えばモビルスーツのクラスと、そのサブクラスがあったとする。

弟子D:はい。

師匠T:そのサブクラスそれぞれに格闘戦を表すメソッドがあったとしても、それぞれのモビルスーツによって、どうやって格闘戦を行うかは違ってくるじゃろ? ザクはヒートホークじゃが、ガンダムはビームサーベル、モビルファイターは拳で、というようにの。

弟子D:なるほど!

師匠T:このように、それぞれによって、実際の内容が違うのが、多態性、ポリモーフィズムというのじゃ。覚えておくがよい。

弟子D:はい!

師匠T:さて、次回はfinal修飾子について説明する。予習復習を忘れてはならぬぞ。ふぅ……さすがに疲れたわい。

弟子D:師匠ももうと……。

師匠T:はぁっ!!(飛び蹴り)

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