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

プログラミング歴ゼロの初心者がもがくサイトです

サブクラスのフィールドの定義の方法で失敗したのでシェアします

サブクラスのフィールドにアクセスしたらnull0しか返ってこず足が止まりました。これはプログラミング初心者あるあるかもしれないので警告しておくとフィールドはオーバーライドできません。そう言われるとそんなことわかってると反論があるかもしれませんが、私たち初心者はなんとなくサブクラスで定義した値が通ると感じませんか?実は通りません。そこで、みんな大好きteratailで解決したので復習しておきたいと思います。

スーパークラスとサブクラスにおけるフィールドの定義の方法

同名フィールドはスーパークラスに定義するべし

スーパークラスMonsterとサブクラスのGoblinです。初心者が見たら違和感はないと思います。では、ここでHeroクラスのattackメソッドを呼び出します。

7行目のmonster.nameと9行目のmonster.hpの中はどうなっていると思いますか?なんと、ここで冒頭ではなしたnull0が登場するんです。私はてっきりゴブリン10にアクセスしていると思っていました。頭の中が真っ白です。しかし、私の知識では検索しようにも適切なワードが出てきませんでした。真っ白のなかterateilで得られた答えは同じ意味を持ったフィールドは基底クラスにのみ宣言することだったんです。

基幹クラスに宣言とは

サブクラスであるGoblinにはフィールドを定義せずにスーパークラスであるMonsterに定義するということでした。Monsterクラスの6~11行目のコンストラクタを定義しておきGoblinクラスの4~6行目のコンストラクタのsuperで、さきほど定義しておいたMonsterクラスのコンストラクタを呼び出すという方法です。目からうろこですね!

Monsterクラスの7~8行目のassertは指定した条件がtrueでない場合にエラーになるという仕組みみたいです。初めて見ました。

結果

見事に各フィールドにアクセスできました!試しに残りのHPも表示してみました。他にもgetNameの定義とサブクラスでのオーバーライドなどの情報をいただきました。もやもやしていた部分が今回ですっきりしました。

あとがき

とある、気になった質問を試していたらfor文のネストもすっきりしたので次回に書いてみます。