Java奮闘記 メモ
- はじめに
- 練習用に作っているRPGシステム
- Scanner利用時のNoSuchElementException
- キーボード入力(BufferedReader or Scanner)
- 条件分岐とreturn
- protected
- 文字化け
- 親クラスのフィールドを子クラスで初期化したい
はじめに
環境などは以下の記事をご覧いただきたい。
なおこの記事は良さげな記事やつまづいた点などを列挙している。
papyrustaro.hatenablog.jp
練習用に作っているRPGシステム
コードです。随時更新。
github.com
Scanner利用時のNoSuchElementException
詳しくは以下の記事を参考
qiita.com
ts0818.hatenablog.com
律儀にclose()をしているときに起こった例外
キーボード入力(BufferedReader or Scanner)
キーボード入力をどちらでおこなうか
上記のcloseの問題もあるので、BufferedReaderのみ使っていこうと思う。
実際に使っているコード例
public static int menu(Ally ally) { int input_menu = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println(ally.name + "はどうする?"); while(input_menu <= 0 || 4 <= input_menu){ System.out.println("1.通常攻撃 2.ヒール 3.調べる"); try { input_menu = Integer.parseInt(br.readLine()); }catch(Exception e) { System.out.println("数字を入力してください"); } } return input_menu; }
以下参考記事。
reasonable-code.com
良記事
キーボード入力の他様々な事が書かれている。
お世話になりそうだ。
qiita.com
条件分岐とreturn
Javaに限った話ではないが条件分岐先でreturnしようとするとき、
その分岐が網羅されているかどうか判断はしてくれない。
よって以下のコードは「〇〇を返す必要があります」みたいなエラーが出る(出た)。
public static Enemy selectEnemy() { Random random = new Random(); int random_num = random.nextInt(2) + 1; switch(random_num) { case 1: return (Enemy)(new Slaim()); case 2: return (Enemy)(new Goblin()); } }
そのため上のコードでは明示的にdefaultかswitch文外でreturnする必要がある。
public static Enemy selectEnemy() { Random random = new Random(); int random_num = random.nextInt(2) + 1; switch(random_num) { case 1: return (Enemy)(new Slaim()); case 2: return (Enemy)(new Goblin()); } return (Enemy)(new Slaim()); }
protected
カプセル化のためフィールドはすべてprivateが望ましい、
みたいな事が言われているが、
サブクラスからスーパークラスのフィールドを使おうとするとかなり面倒。
なのでprotectedにすると、
同パッケージならどこからでもアクセスできてしまう。
protectedは名前からしてガードが堅いイメージを持っていたが、そうでもない。
なぜサブクラスからはアクセスできて同一パッケージからはアクセスできない修飾子はないのだろうか。
パッケージを分けるのが定石なのかもしれない。
文字化け
いつものようにプログラムを実行していたら、あるとき文字化けが発生した。
画像を見てわかる通り、すべて文字化けしているわけではない。
しかし、変更していないメソッドの部分の文字列も文字化けしているので、これはなんだ、と。
最初BufferedReaderやStirng型配列を変に使っているせいなのか、とも考えたが、
Eclipseの文字コードの設定を片っ端からUTF-8にしたら直った。
はっきりとした原因はわからなかったが、化け文字が発生したときはまず文字コードを疑うべきかもしれない。
以下参考記事↓
qiita.com
親クラスのフィールドを子クラスで初期化したい
親クラスでフィールドの宣言をして、子クラスでそれぞれ別々に初期化したいとき。
親クラスで宣言→子クラスのコンストラクタで初期化
こうすることで親クラスからフィールドを参照でき、
かつ子クラス毎に別々の値を持つことができる。
以下のようなコードは目にしたことがあるだろう
class Character{ String name; int hp; Character(String name, int hp){ this.name = name; this.hp = hp; } } class Ally extends Character{ int mp; Ally(String name, int hp, int mp){ super(name, hp); this.mp = mp; } }
配列の初期化はこうした。
パフォーマンスなどは怪しい。
class Character{ String name; String[] skill_name; Character(String name){ this.name = name; } } class Ally extends Character{ Ally(String name){ super(name); this.skill_name = new String[]{"連続切り", "ヒール"}; } }