サブクラスのフィールドの定義の方法で失敗したのでシェアします
サブクラスのフィールドにアクセスしたらnull
と0
しか返ってこず足が止まりました。これはプログラミング初心者あるあるかもしれないので警告しておくとフィールドはオーバーライドできません。そう言われるとそんなことわかってると反論があるかもしれませんが、私たち初心者はなんとなくサブクラスで定義した値が通ると感じませんか?実は通りません。そこで、みんな大好きteratailで解決したので復習しておきたいと思います。
スーパークラスとサブクラスにおけるフィールドの定義の方法
同名フィールドはスーパークラスに定義するべし
スーパークラスのMonster
とサブクラスのGoblin
です。初心者が見たら違和感はないと思います。では、ここでHero
クラスのattack
メソッドを呼び出します。
7行目のmonster.name
と9行目のmonster.hp
の中はどうなっていると思いますか?なんと、ここで冒頭ではなしたnull
と0
が登場するんです。私はてっきりゴブリン
と10
にアクセスしていると思っていました。頭の中が真っ白です。しかし、私の知識では検索しようにも適切なワードが出てきませんでした。真っ白のなかterateilで得られた答えは同じ意味を持ったフィールドは基底クラスにのみ宣言することだったんです。
基幹クラスに宣言とは
サブクラスであるGoblin
にはフィールドを定義せずにスーパークラスであるMonster
に定義するということでした。Monster
クラスの6~11行目のコンストラクタを定義しておきGoblin
クラスの4~6行目のコンストラクタのsuper
で、さきほど定義しておいたMonster
クラスのコンストラクタを呼び出すという方法です。目からうろこですね!
Monster
クラスの7~8行目のassert
は指定した条件がtrue
でない場合にエラーになるという仕組みみたいです。初めて見ました。
結果
見事に各フィールドにアクセスできました!試しに残りのHPも表示してみました。他にもgetName
の定義とサブクラスでのオーバーライドなどの情報をいただきました。もやもやしていた部分が今回ですっきりしました。
あとがき
とある、気になった質問を試していたらfor文のネストもすっきりしたので次回に書いてみます。