11/6の課題について、 class Kadai1106{ public static void main(String [] args) throws Exception{ BufferedReader d=new BufferedReader(new InputStreamReader(System.in)); // 試行回数times,正解Moo数a,入力Moo数q,bull&cowの数b,c,入力用文字列strの定義 int times=0,b,c; MooNumber a,q; a=new MooNumber(); System.out.println(a); String str; System.out.println("Guess a Moo number"); while(true){ //while文を繰り返す毎にtimesを+1 times=times+1; //qの入力と判別 str=d.readLine(); q=new MooNumber(str); //bull,cowの数を調べる b=MooNumber.getBull(a); c=MooNumber.getCow(a); //正解ならwhile文を抜ける if(b==4) break; //不正解ならB,Cを表示し繰り返し else System.out.println(times+":"+b+"B"+c+"C"); } System.out.println(times+":"+b+"B"+c+"C"); System.out.println("Correct answer in "+times); } } というクラスを作ったのですが、これを走らせようとするとまず getBull/getCowはnon-staticなので参照できないという主旨のコンパイルエラー が出ました。文字列に変換してからintに再変換しようなどと方針を変えても 同じ結果になるので、MooNumberクラス内のgetBull/Cowメソッドに static int getBull(MooNumber m){ というようにstatic属性を追加してみました。これを走らせようとすると今度 は配列digits[]がnon-staticであるというエラーが出たのでこれにもstaticを 追加しました。(これがプログラムにどのような影響を及ぼしているのかは、 理解していません) これでプログラムは走るようにはなったのですが、走らせてみるとどんな答え を入力しても必ず正解になってしまうという現象が起りました。原因究明のた め System.out.println(a); をあちこちに挟んでみるとどうやら入力Moo数qの値を、文字列strを元に代入 した時点でqと同時に正解aにもその値が代入されているらしいことがわかりま した。プログラムをいくらいじり回してもこれは直ることがなく、情報棟閉館 時間になったので断念してしまいました。 Javaに関するWEBサイトをあたってもみましたが知識が大雑把なのでどうして もどこで間違えているのかが理解できません(MooNumberクラスに手をつけて いる時点でおかしいのでしょうが)。ご指導願います。 |
> これを走らせようとするとまずgetBull/getCowはnon-staticなので参照できな > いという主旨のコンパイルエラーが出ました。 はい. > b=MooNumber.getBull(a); という書き方は 静的メソッド(static method) (http://lecture.ecc.u-tokyo.ac.jp/~ktanaka/programming01/1030-3.html) の呼び出し方ですが,定義の方では, > int getBull(MooNumber m){ のように,staticをつけないすなわち動的メソッドとして定義しているので, コンパイラはそのようなエラーを出します. さて, > b=MooNumber.getBull(a); という式では q と a の間の bull を計算したいはずなのに,aしか出てきて いませんね.動的メソッド (http://lecture.ecc.u-tokyo.ac.jp/~ktanaka/programming01/1030-4.html) の呼び出し方を見直してみると正解にたどり着けると思います. > これを走らせようとするとまずgetBull/getCowはnon-staticなので参照でき >ないという主旨のコンパイルエラーが出ました。文字列に変換してからintに >再変換しようなどと方針を変えても同じ結果になるので、MooNumberクラス内 >のgetBull/Cowメソッドに > static int getBull(MooNumber m){というようにstatic属性を追加し >てみました。これを走らせようとすると今度は配列digits[]がnon-staticであ >るというエラーが出たのでこれにもstaticを追加しました。(これがプログラ >ムにどのような影響を及ぼしているのかは、理解していません) プログラミングにおいては,意味を理解しないで変更してうまくいくという 幸運に恵まれることはそうはありません.この変更は, http://lecture.ecc.u-tokyo.ac.jp/~ktanaka/programming01/1030-4.htmlの ページの最後に > クラス内の変数の宣言に static をつけると,クラス変数といって,そのク > ラスのインスタンスを作らずに参照できる変数ができる.これまでには, > Math.PIなどが出てきた.しかし,通常のプログラミングではそれほど問題に > ならない. と書いたように,配列 digits[] をクラス変数にしたのですが,このようにす ると digits はインスタンス,すなわち, > a=new MooNumber(); > q=new MooNumber(str); などで作ったものごとに別々な実体を持つものではなく,クラス中のすべての インスタンスで共有する変数になります.そのため,新たに MooNumberを作っ て q に入れるたびに,aの中身も入れ替わって見えるわけです. |
ヒントをいくつか与える.
public String toString(){ return ""+digits[0]+""+digits[1]+""+digits[2]+""+digits[3]; }と定義してある.これを利用して,
MooNumber a=new MooNumber(); System.out.println("Moo number is "+a);のようにデバッグ用の表示が楽にできる.
bull=a.getBull(b);のようにして計算できる.
オプション課題はネットニュースと掲示板に1つづつ投稿があった.こちらに 関する講評は次回以降おこなう.なお,オプション課題の提出期限は特にもう けないので,講義期間中にそれまでなかったような自信作ができたら,いつで も投稿して欲しい.