第5回講義

download report

Transcript 第5回講義

オブジェクト・プログラミング
第5回
オブジェクト指向入門
手続き指向からオブジェクト指向へ(2)
今日の目標

クラスを使ったプログラミングができるようになる。
(続き)



クラスの配列を使うことができるようになる。
コンストラクタを使うことができるようになる。
クラスを使ったプログラミングの利点を説明でき
るようになる。


責任ごとにクラスを分ける利点を説明できるようにな
る。
責任ごとに分けられたクラス図を見て、実装できるよう
になる。
前回多かった質問


ItemInfo iteminfo1 = new ItemInfo();
↑これどういう意味?
変数の型

変数とは?

プログラムで使うために、情報を保存しておく
箱
103
itemNo
変数の型(2)


箱にもいろいろな箱がある!
箱の種類のことを「型」といいます。
0.849
103
整数が入る箱
int
コーラ
小数が入る箱
文字列が入る箱
String
true
真偽値が入る箱
double
boolean
変数の型(3)

型が違うと代入することができません。
0.849
コーラ
整数が入る箱
文字列が入る箱
変数の宣言

int itemNo;

String itemName;
itemNo
:整数型
itemName
:文字列型
変数の代入

77
itemNo = 77;
itemNo
:整数型

=の意味は、右側の値を左側に代入せ
よ!
という意味です。知ってた?
じゃあこれはどういう意味?

ItemInfo iteminfo1 = new ItemInfo();
①
③
1.ItemInfoクラスのオブジェクトが入
るiteminfo1という名前の箱を作る。
2.ItemInfoクラスをインスタンス化す
る。
3.インスタンス化したItemInfoオブ
ジェクトを作った箱に代入する。

②
ItemInfo
オブジェクト
iteminfo1
:ItemInfo型
だけど実は、、

ItemInfoをインスタンス化する。
→その中にまた箱ができる。
public class ItemInfo{
int no;
String name;
}
ItemInfoオブジェクト
no
:整数型
name
:文字列型
オブジェクトの変数への代入

iteminfo1.no = 77;
ItemInfoオブジェクト
77
no
:整数型
name
:文字列型
iteminfo1
:ItemInfo型
クラスを使ったプログラミング
(続き)
・たくさんのItemInfoを扱う(配列)
・クラスを使う際に便利なテクニック
(コンストラクタ)
先週の復習(1)

要求:


商品番号だけでは取扱商品ぽくない。
商品名を扱いたい。
先週の復習(2)
クラス図
たくさんのItemInfoを扱う

とりあえず10個のItemInfoを扱えるように
します。
VendingMachineMain
main()
insert(target : int[], registerKey : int)
delete(target : int[], deleteKey : int)
search(target : int[], searchKey : int)
display(target : int[])
1
0..10
ItemInfo
no : int
name : String
ItemInfoの配列を作る
ItemInfo型
[0]
[1]
[2]
[3]
[4]
続くよ
itemInfoArray(配列全体の名前)
クラスの配列を作る
(Javaでの記法)
intの時と基本的には同じです。
ItemInfo型
[0]
[1]
[2]
[3]
[4]
続くよ
ItemInfo[] itemInfoArray = new ItemInfo[10];
intの配列との大きな違い
int型
0
0
0
0
0
0
0
0
0
0
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
intの配列のとき、配列には初期値として、
0が入りました。
ItemInfo型の初期値
ItemInfo型
[0]
[1]
[2]
[3]
[4]
初期値には「何も入っていない!!」
続くよ
オブジェクトが何も入っていない状態のことをnullといいます。
!だから前回は「0が入っていたら、取扱商品が入っていない」
ということでしたが、
今回は「何も入っていなかった(null)ら、取扱商品が入っていない」
ということになります。
ItemInfo配列への代入
ItemInfo
オブジェクト
no name
[0]
[1]
[2]
[3]
[4]
[5]
続くよ
ItemInfo[] itemInfoArray = new ItemInfo[10];//配列を作る
itemInfoArray[0] = new ItemInfo();//ItemInfoオブジェクトを作って代
itemInfoArray[0].no = 77;
itemInfoArray[0].name = “コーラ”;
何も入っていない箱のオブジェク
トにアクセスしてはいけない。

次のプログラムを実行してみましょう。
//これはまずいプログラム
public class FailProgram{
public static void main(String[] args){
ItemInfo[] itemInfoArray = new ItemInfo[10];//配列を作る
itemInfoArray[0].no = 77;
itemInfoArray[0].name = “コーラ”;
}
}
コンパイルは通ります。
ですが!実行すると!!
例外

前ページのプログラムを実行すると、
NullPointerExceptionと表示がでてプログラムが
とまります。


これは、オブジェクトが入っていないのにアクセスした
ので、処理できません。プログラムを終了します。とい
う意味です。あなたのプログラムのバグです。
この他にも例外があります。

ArrayIndexOutOfBoundsExceptionは、配列にはない
番地(例えば10つの配列の[10])を読もうとしましたよ
という意味です。あなたのプログラムのバグです。
ItemInfoを使った挿入のプログ
ラム
前回までの
プログラム
今回の
プログラム
public static void insert(int[] target,int registerKey){
for(int i = 0;i<10;i++){
if(int[i] == 0){
target[i] = registerKey;
break;
}
}
}
public static void insert(ItemInfo[] target,ItemInfo registItem){
for(int i = 0;i<10;i++){
if(target[i] == null){
target[i] = registItem;
break;
}
}
}
ItemInfoを使った場合のmain
//ItemInfoの配列を使って挿入するプログラム
public class VendingMachineMain{
public static void main(String[] args){
ItemInfo[] itemInfoArray = new ItemInfo[10];
ItemInfo itemInfo = new ItemInfo();
itemInfo.no = 77;
itemInfo.name = “コーラ”;
insert(itemInfoArray,itemInfo);
}
…
}
これを10個書くのは
長ったらしくてうれしくないですね。
Javaのテクニック:コンストラクタ

要求:ItemInfoをインスタンス化すると同
時に変数を代入したい。
→コンストラクタを使うとできます。
コンストラクタ(1)宣言
//簡単なコンストラクタをつけたItemInfoクラス
public class ItemInfo{
int no;
String name;
}
同じ名前にすること!
public ItemInfo(){
}
☆クラス名と同じ名前で、メソッドのようなものを
宣言します。
☆メソッドと違ってvoidなどの返り値宣言
がいりません。(staticもいりません)
コンストラクタ(2)引数
//引数をつけたコンストラクタのあるItemInfoクラス
public class ItemInfo{
int no;
String name;
public ItemInfo(int initNo,String initName){
}
}
コンストラクタにも引数を書くことができます。
コンストラクタ(3)代入
//引数を代入するコンストラクタを持つItemInfoクラス
public class ItemInfo{
int no;
String name;
public ItemInfo(int initNo,String initName){
no = initNo;
name = initName;
}
}
noとnameに値が代入されます。
属性はクラススコープの変数
//便利なコンストラクタを持つItemInfoクラス
public class ItemInfo{
int no;
String name;
public ItemInfo(int initNo,String initName){
no = initNo;
name = initName;
}
}
noとnameの有効範囲
コンストラクタ(4)呼び出し
//コンストラクタを呼び出してインスタンス化する例のプログラム
public class VendingMachineMain{
public static void main(String[] args){
ItemInfo[] itemInfoArray = new ItemInfo[10];
ItemInfo itemInfo = new ItemInfo(77,”コーラ”);
insert(itemInfoArray,itemInfo);
}
77とコーラが実引数として渡され、
…
コンストラクタが呼ばれることによって、
}
できたてのitemInfoオブジェクトに変数が代入されます。
もっと簡略化
//全ページの例を余計な変数を使わないようにしたプログラム
public class VendingMachineMain{
public static void main(String[] args){
ItemInfo[] itemInfoArray = new ItemInfo[10];
insert(itemInfoArray, new ItemInfo(77,”コーラ”));
}
…
}
変数に保存しておく必要がないので、
インスタンス化して、そのままメソッドの実引数
として使います。
改良してできたクラス図
VendingMachineMain
main()
insert(target : ItemInfo[], insertInfo : ItemInfo)
delete(target : ItemInfo[], deleteKey : int)
search(target : ItemInfo[], searchKey : int)
display(target : ItemInfo[])
1
0..10
ItemInfo
no : int
name : String
責任ごとにクラスを分ける
さらにオブジェクト指向
main()になった気持ちで考えて
みよう!
大変!!
main()
[0][1][2][3][4][5][6][7][8][9]
mainの言い分



私は、取扱商品の管理だけしてればいい
わけではないの。
これから、実際の商品の処理とか、お金の
処理とかたくさんやらなければいけないこ
とがあるの。
商品情報管理をもっと楽にできる方法がな
いかしら?
そこで!
こんなオブジェクトがあったら便利ですね!
挿入
削除
main()
検索
取扱商品情報フォルダ
(オブジェクト)
[0][1][2][3][4]
取扱商品情報フォルダクラスの
導入
取扱商品情報フォルダ
クラス
取扱商品情報フォルダ
(オブジェクト)
導入後のクラス図
これを実装するのが今日の課題
ItemInfoFolder
VendingMachineMain
main(args : String[])
取扱商品情報の操作の
順番に責任を持つ
insert(insertInfo : Iteminfo)
delete(deleteKey : int)
search(searchKey : int)
display()
取扱商品情報を
管理する責任を持つ
1
0..n
ItemInfo
no : int
name : String
取扱商品情報の保持に
責任を持つ
クラスの分け方は難しいが
「責任」ごとに分けるとうまくいく場合が多い。
このプログラムを課題に使ってください。
導入後のmainプログラム
public class VendingMachineMain{
public static void main(String args[]){
ItemInfoFolder folder = new ItemInfoFolder();//取扱商品情報フォルダを作成
}
}
//取扱商品情報をいくつか挿入
folder.insert(new ItemInfo(77,”コーラ”));
folder.insert(new ItemInfo(99,”サイダー”));
folder.insert(new ItemInfo(44,”オレンジ”));
folder.insert(new ItemInfo(55,”アップル”));
…
//取扱商品情報を表示
folder.display();
//商品番号77を検索
folder.search(77);
//商品番号55を削除
folder.delete(55);
//取扱商品情報を表示
folder.display();
mainはややこしい
配列の管理をする必要が
なくなった。
オブジェクトのメソッドの呼び出し
ItemInfoFolder folder = new ItemInfoFolder();
folder.insert(new ItemInfo(77,”コーラ”));
呼び出し方は属性の呼び出しと同じです。
オブジェクト名.メソッド名
で呼び出します。
メソッドを移すだけジャン!?


今日はそう思われる方も多いでしょう。
実は利点はたくさんあります。


だんだんわかってくるはずです。
今日はいくつか取り上げます。
うれしいこと(1)
挿入
削除
main()
取扱商品情報フォルダ
(オブジェクト)
検索
mainはフォルダのインターフェースだけを知っています。
データ構造をカプセル化できる
挿入
削除
main()
検索
取扱商品情報フォルダ
(オブジェクト)
[0][1][2][3][4]
実はここに配列がありますがmainは知りません
何故うれしいのか?



mainが配列を知らないことは何故嬉しい
のでしょうか?
実は、配列を使わなくても、挿入、削除、検索ができる
のです。
→もう少しあとにやります。
その時に、mainを全部変更するのは大変で、バグの
原因になります。クラスにしておけば、クラスを取り替
えるだけで済みます。
うれしいこと(2)
分担作業が楽にできます。
Bさんは
このクラスを作る
Aさんは
このクラスを作る
(Folderのインターフェースさえ知っておけば簡単に合体できます。)
うれしいこと(3)

便利なFolderは使いまわしが可能。

自動販売機だけでなく、取扱商品情報を管理
するようなすべてのプログラムで再利用が可
能。
ItemInfoFolderクラスをJavaで
実装する
//コメントは省略
public class ItemInfoFolder{
public void insert(ItemInfo insertInfo){
//あれ?何処に入れたらいいの?
}
//search,delete,displayメソッドも書く
}
属性にItemInfoの配列を加える
//コメントは省略
public class ItemInfoFolder{
ItemInfo[] iteminfo = new ItemInfo[10];//ItemInfoの配列
public void insert(ItemInfo insertInfo){
}
//search,delete,displayメソッドも書く
}
insertメソッドを実装する
//コメントは省略
public class ItemInfoFolder{
ItemInfo[] iteminfo = new ItemInfo[10];//ItemInfoの配列
}
public void insert(ItemInfo insertInfo){
for(int i=0;i<10;i++){
if(iteminfo[i] == null){
iteminfo[i] = insertInfo;
break;
}
}
}
//search,delete,displayメソッドも書く
今週の課題

ItemInfoFolderクラスの残り
(search,delete,displayメソッド)を完成させ、
プログラムを動かしなさい。


今回もファイルは3つになります。
(VendingMachineMain.java,ItemInfo.java,
ItemInfoFolder.java)
ヒント:

searchメソッドもdeleteメソッドも、前回のプロ
グラムを一工夫する必要があります。
提出方法



[email protected]宛て。
今回もファイルが3つになるので、添付す
る人は必ず一つのファイルにまとめてから
送ってください。 (圧縮不可)
Subjectはログイン名を必ず書いてください。



ex) t96844ym
余計な[]などをつけないでください。
水曜まで。
補足説明

何故今日のプログラムはメソッドにstaticを
つけなくていいのか?



staticは「クラスメソッド」という意味で、クラスに
つくメソッドである。(Javaでは)
インスタンス化したオブジェクトのメソッドを呼
ぶためには必要ない。
VendingMachineMainクラスは誰からもインス
タンス化されないので、staticが必要。