プログラミングいちねんせい

プログラミング初心者が優雅にもがく軌跡です

JAVAの継承について考える 第1回目

猫も犬も大きくとらえれば動物です。そして動物や植物は大きくとらえれば生物です。オブジェクト指向であるJAVA現実世界のふるまいを仮想世界で再現することらしいのでCreatureインターフェースを作りAnimalクラスで実装しCat, Dogクラスで継承してみました。便利だと感じると同時に大きな疑問も残ったので、それをシェアしたいと思います。

継承のテスト 1

それでは、ひとつずつ見ていきます。

Creature.java

Creatureインターフェースです。生き物は走ったり鳴いたりするはずと考えたのですが植物は走りませんし鳴きませんから、これは失敗です。そう考えるとCreatureインターフェースに定義できるメソッドはeatでしょうか。そのへんの掘り下げは今回は置いときましょう。インターフェースなので以下の2つの条件をクリアーしています。

  1. フィールドを持たない
  2. メソッドがabstractである

Animal.java

Creatureインターフェースを実装したAnimalクラスです。ここで疑問がわきました。多様性を持たせるためにAnimalクラスをインスタンス化したいのですがrun()メソッドもbark()メソッドもAnimalクラスの段階では内容が決まっていません。羽があるのかないのかもわかりません。しかし、ここでabstractをつけてしまうとインスタンス化ができないという悩みが生まれます。オブジェクト指向としては間違っているかもしれませんが、とりあえず逃げた鳴いたと定義しました。

Cat.java, Dog.java

親クラス(継承元)であるAnimalクラスのbark()メソッドとrun()メソッドをオーバーライドしています。継承した場合はオーバーライドしないとエラーになるので忘れないようにします。ここで注目してほしいのがAnimalクラスにはなかったtraning()メソッドです。動物の時点ではしつけができない動物も含まれるのでCatクラスDogクラスで定義しました。

Main.java

ここでオブジェクト指向の武器である多様性を発揮させます。猫も犬もざっくり見れば動物と考えることで9行目でAnimal型のanimal[]配列のなかにcatdogを入れます。わざわざ配列のなかに入れることでなにをするかというと12行目を見てください。拡張for文です。for ( 型 変数名 : コレクション名)という順番で指定します。ここでの変数名は拡張for文のなかでしか使われないローカル変数です。わかりやすい好きな名前をつけてください。ここではaと指定しましたがinなどでもかまいません。

13行目のa.bark();1行でCatクラスとDogクラスのそれぞれのbark()メソッドを呼び出しています。それぞれをざっくりと動物として考えることで多様性のメリットが利用できました。14行目も同じです。そして15行目ですがtraning()メソッドはAnimalクラスで定義していませんのでコメントアウトを外すとエラーになります。多様性を利用できるのは親クラスが持つメソッドのみということですね。最後は18,19行目でtraning()メソッドを呼び出して終わりです。

result

生まれた疑問

  • 多様性を利用したい場合Animalクラスのそれぞれのメソッドはどう定義すればよかったのか?

インスタンス化したいのでabstractにするのは論外ですが今回のように強引に実装するのは間違っていると感じました。しかし解決策が見当たりません。

まとめ

手探りながら文章化して説明すると気付かされることが多いので勉強になるのですが時間がかかるのが難点です。もっとたっぷりと勉強したい!