[[Lecture]] //#contents *マルチメディアプログラミング実習 2016年10月27日 [#l5a64c51] **第6章 クラスの基礎 [#j390b306] ***クラスとインスタンスの説明をしました。復習しましょう。 [#nc29f87c] -クラスは型、インスタンスはそれから作られたもの --クラスがたいやきの焼き型だとすると、インスタンスはそれから作られたたいやき --クラスは設計図でインスタンスはそれから作られたもの -クラスとインスタンスそれぞれにメソッドと変数がある --クラス変数 例:何個のインスタンスを作ったか? --クラスメソッド 例:インスタンスを作れ --インスタンス変数 例:ひとつのたいやきの重さ --インスタンスメソッド 例:たいやきをxxグラム食べる http://gyazo.com/bbdd3587977a172f7fa7f00c4f5787e0.png クラスメソッド、クラス変数は、クラスに聞きます。 インスタンスメソッド、インスタンス変数は、インスタンスに聞きます。 例えば、上の例で、クラス名がTaiyakiでインスタンスがtaiyaki1, taiyaku2,...だとすると、 クラスメソッド、変数は、 Taiyaki.yaku(); とか Taiyaki.seizousuu とかしてアクセスします。 インスタンスメソッド、変数は、 taiyaki1.taberu() とか taiyaki2.ondo とかしてアクセスします。 **第7章 クラスとオブジェクトの操作 [#kee2d2bd] ***7.1 オーバーロード [#m83a13c4] 先週、説明しました。教科書pp.101--104を読んで復習してください。 (10分) 他の点との距離を返すメソッドの例を使ってオーバーロードを説明しました。 double distance ( int ptx, int pty ) { int dx = ptx - this.x; int dy = pty - this.y; return Math.sqrt(dx * dx + dy * dy); } double distance ( Point p ) { return this.distance(p.getx(), p.gety()); } distanceという名前は同じでも、引数の違いで、異なる動作をさせることができます。 ***7.2 コンストラクタ [#o49a6e8b] 今まではnew Point()と言うようにしてインスタンスを作っていました。 Point()と言うメソッドは、クラスメソッドの特別なものです。 インスタンスを作るときに、他にやってほしい仕事をコンストラクタに書くことができます。 教科書のpp.104--107を読んでください。(10分) 前回作ったPoint3Dクラスに、new Point(10,20,30)をするとx,y,z=10,20,30の点を作ってくれるコンストラクタを書いてみてください。 ***7.3 インスタンスの参照 [#f314be52] pp.107--109を読んでください。(10分) インスタンスを指している変数を理解してください。Cで言う所のポインターになっています。 ***7.4 ガーベージコレクション、ファイナライザ [#n218282d] 7.4節を読んでください(5分) Cではmalloc()して得たメモリーは、いつかは、free()してあげないと、どんどんメモリーを消費してしまうプログラムになってしまいます。 メモリーを要求するだけで返却しないプログラムが、メモリーをどんどん浪費していく現象は、 メモリーリークとも呼ばれます。 一見動いていても、長時間動かしていると落ちてしまうタチの悪いバグです。 Javaでは使わなくなった(参照されなくなった)インスタンスが使うメモリーを、自動的に返却する機能、ガーベージコレクション(ゴミ集め)があります。 なので、free()に相当することをやらなくて良いのです。 インスタンスが破棄される直前に、何かの処理をしたい場合は、finarize()メソッドを定義しておきます。 ***7.5 インスタンスのメンバとクラスのメンバ [#e5b13cf2] 7.5節を読んでください。プログラム7.4も読んでください(15分) メンバというのは変数とメソッドの総称です。 staticなメンバとは、クラス変数、クラスメソッドのことです。 staticではないメンバが、インスタンス変数、インスタンスメソッドになります。 ***7.6 ファイナル変数 [#t24c3717] 7.6節を読んでください(5分) C言語では#define文で定数を定義することがありました。 Javaにはそういう仕組みがありません。 定数を定義したいときには予約語finalを使います。 これはこの後変更されない変数になります。 ***7.7 アクセス制御 [#o5312e4c] 7.7節を読んでください(5分) publicとprivateは知っておくと良いです。 //TAの方へ:教科書の自習が終了したら、以下の課題を公開してやってもらってください。 //コメントを外して、リロードしてもらってください。 //----------------------- // **本日の課題 [#h02fd642] ここまで教科書を読んだら、次のOsaifuプログラムを書いてください。 *** Osaifuクラスを作ってみよう [#nf25f9f7] -Osaifuクラスからはインスタンスがたくさん作られる --Osaifuクラスはお財布の設計図/工場、ここから実際のお財布(インスタンス)が複数作られる --工場出荷時の残金は0円だけど、その後、いろいろな値になるだろう(お金持ちのお財布には残金が多いだろうし、逆ならば少ないだろう) --ということで残金はインスタンス変数とすべきだろう -Osaifuクラスには次のメソッド、変数が必要だろう --残金を表すインスタンス変数 int okane --お金を入金するインスタンスメソッド void in(int x); --お金を出金するインスタンスメソッド int out(int x); 戻り値は実際に出金できた金額(残金が不足ならばあるだけしか出せない) --残金を印刷するインスタンスメソッドがあってもよいだろう void print(); &br; http://gyazo.com/bd6eaafd220dc7ff791288089f293b28.png -Osaifuクラスをテストするmain()メソッドでは次のことをやってください -- Osaifuインスタンスを一つ作ってそれをsaifu1という名前にする -- Osaifuインスタンスをもう一つ作ってそれをsaifu2という名前にする --saifu1に1000円入金する --saifu2に500円入金する --saifu1とsaifu2が持っている金額を印刷する --saifu1から200円出金してそれをsaifu2に入金する --saifu1とsaifu2が持っている金額を印刷する このOsaifuクラスを作ってください。 mainに、以下のテストプログラムを書いてください。 public static void main(String argv[]) { Osaifu saifu1 = new Osaifu(); Osaifu saifu2 = new Osaifu(); saifu1.in(1000); saifu2.in(500); saifu1.print(); saifu2.print(); saifu2.in(saifu1.out(200)); saifu1.print(); saifu2.print(); } すると結果は以下になるはずです。 http://gyazo.com/c618901458edc1ba338cab87d2810157.png //TAの方へ:ここまでを最初に公開 //TAの方へ:大部分の人ができたようでしたら、 //以下の解答編を公開してください。コメントを外して、リロードしてもらってください。 ***解答編(簡易版) [#te4d9e40] public class Osaifu { int okane; public void in (int x) { okane += x; } public int out(int x) { okane -= x; return x; } public void print() { System.out.println( "okane = " + okane +" yen"); } public static void main(String argv[]) { Osaifu saifu1 = new Osaifu(); Osaifu saifu2 = new Osaifu(); saifu1.in(1000); saifu2.in(500); saifu1.print(); saifu2.print(); saifu2.in(saifu1.out(200)); saifu1.print(); saifu2.print(); } } //TAの方へ:できなかった人に上記の解答を示すと同時に、 //できた人には、以下の方策を考えてもらってください。 --このプログラムでは残金がマイナスになってしまってもかまわない設計になってしまっています。実際には残金だけの金額しか出せないはずなので、outメソッドを改良して、残金以上の金額を要求されたら、残金分だけしか出さないように変更してみてください。 // //TAの方へ:はんぶんくらいの人がoutメソッドの改良に成功したくらいで、以下の //解答編を公開してください。 --このためには、例えばoutメソッドを以下のようにすれば良い public int out(int x) { if(x < okane ) { okane = okane -x; return x; } else { int nokori = okane; okane =0; return nokori; } } //全部の人がOsaifuクラスを実装できたら(上記のoutメソッドのマイナス問題は全員ができなくても良いです) //教科書のコンストラクタのページを見て考えてくださいと指示して、 //以下をコメントアウトして、課題を進めてもらってください。 *** つぎにOsaifuクラスにコンストラクタを追加してみよう [#p5f7ab1d] -Osaifu() で残金0のインスタンスを作る -Osaifu(int x) で引数を残金の初期値としたインスタンスを作る ことができるコンストラクタを作ろう。 これをmainから呼んで、上記のプログラムと同じことをするためには、 Osaifu saifu1 = new Osaifu(1000);//インスタンスを作る //最初の保持金額を1000円にする Osaifu saifu2 = new Osaifu(500);//インスタンスを作る //最初の保持金額を500円にする とすることになる。mainを書き換えて確かめてください。 //TAの方へ:半分くらいの人が完成したら、課題提出を開始してもらって、 //さらに以下の解答編を提示して、全員が完成して課題提出できるようにしてください。 //***コンストラクタ解答編 [#x26f38d7] // //以下のコンストラクタを作ることになる。 // // Osaifu() { okane = 0; } // Osaifu(int x) { okane = x; } // //これは以下のように書いても良い。 // // Osaifu() { this(0); } // Osaifu(int x) { okane = x; } // **コンストラクタ解答編 [#x26f38d7] 以下のコンストラクタを作ることになる。 Osaifu() { okane = 0; } Osaifu(int x) { okane = x; } これは以下のように書いても良い。 Osaifu() { this(0); } Osaifu(int x) { okane = x; } ***課題提出 [#j8e17a4c] 最終的に作ったOsaifu.java, Osaifu.classをいつものように提出してください。