サブゼミ第7回 実装編① オブジェクト型とキャスト 今週のGOAL GOAL ・Object型について理解し、Object型と キャストを用いた効率のよいプログラムが 書ける Objective •Object型について説明できる •継承について軽く説明できる •キャストができるようになる •プログラミング勘を取り戻す 自販機の一部について扱う ・オブジェクト図 自動販売機システム <<オブジェクト図>> 貨幣A : 貨幣情報型 : 取扱貨幣型 貨幣B : 貨幣情報型 貨幣C : 貨幣情報型 商品A : 商品情報型 : 取扱商品型 商品B : 商品情報型 商品C : 商品情報型 概念を用いてサービスを実現する ・クラス図(商品追加、貨幣追加を実装) VendingMachine Appli モデルの問題点を探す 問題のあるモデル 構造がわかりにくく無駄が多いモデル コードが何箇所かで重複している 現在のモデルの問題 •取扱商品と取扱貨幣に似たコードがある public void 貨幣追加(貨幣情報型 追加貨幣情報){ 貨幣情報リスト[貨幣要素数]=追加貨幣情報; 貨幣要素数++; } public void 商品追加(商品情報型 追加商品情報){ 商品情報リスト[商品要素数]=追加商品情報; 商品要素数++; } 配列を管理する機能についてのコードが重複している! 配列を管理するクラス ・クラス図改(配列を管理するクラスを追加) 自動販売機 <<クラス図>> 商品情報型 商品名 : String 商品情報ID : int 価格 : int 取扱商品型 商品追加() 商品表示() 1 0..n get価格() get商品情報ID() get商品名() 配列リスト型 要素数 : int VendingMachine Appli 追加() 取得() get要素数() 取扱商品は配列リスト型を 使って商品情報型を持つ 貨幣情報型 貨幣情報ID : int 価値 : int 取扱貨幣型 貨幣追加() 貨幣表示() 1 0..n get価値() get貨幣情報ID() 配列リストクラスの役割 ・配列を管理するとはどういうことか? 今までは取扱商品と取扱貨幣が個別に 商品情報と貨幣情報の配列を用意して使っていた 配列リストクラスが配列を用意し 取扱商品と取扱貨幣は用意された配列を用途に 応じて商品情報や貨幣情報の配列として使う クラスの抽象化 場合によって商品情報の配列としても 貨幣情報の配列としても扱うことが できるようにするにはどうすればいいか? 貨幣情報と商品情報クラスの インスタンスを抽象化してObject型の インスタンスとして扱う Object型とは Javaでは貨幣情報型や商品情報型を含めた すべてのクラスはObject型の特別な形である すべてのクラスのインスタンスはObject型の インスタンスとして扱うこともできる すべてのクラスはObject型を継承している Object型はすべてのクラスを抽象化したもの 抽象化=わかりやすい! 抽象化ってすごくわかりにくい気がしませんか? •石原君 •青山君 •ニホンザルの次郎 君 } みんな呼吸をすることを 説明したい 哺乳類は呼吸をする 抽象化してわかりやすくしている! 継承をクラス図では スーパークラス サブクラス ・・・・・ equals()やtoStringなどの 操作をクラスの中で 宣言しなくても使えるのは Object型を継承している から 継承の例 図には表れないが 呼吸をする()、寝る()などの 操作を持っている 継承をするとどうなる? •抽象化により異なったクラスのオブジェクトを まとめて扱うことができる •スーパークラスのメソッドや変数を サブクラスでも使うことができる •重複コードが減る しかしむやみに継承を使うことは コードがわかりにくくなる原因になります あくまでも「AはBの特別な場合である」 サブクラス スーパークラス というときにしか使わない 配列リストの実装方法 private Object[] リスト;//Object型のインスタンスを配列で持つ : : public void 追加(Object 追加オブジェクト){ リスト[要素数]=追加オブジェクト; 要素数++; } 追加()メソッドはObject型か Object型のサブクラスの インスタンスを受け取ることができる 配列から取り出すとき 配列リスト型の取得()メソッドを使う /** * リストから指定された位置にある配列のオブジェクトを返すメソッド */ public Object 取得(int 取得位置){ return リスト[取得位置]; } オブジェクトを取り出して使う System.out.println((貨幣情報リスト.取得(i)).get貨幣情報ID()); 貨幣情報型 返り血 = 貨幣情報リスト.取得(2); これをコンパイルするとどうなると思いますか? 取得()メソッドはObject型のインスタンスを 返すので貨幣情報型のメソッドである get貨幣情報ID()を呼び出すことができない キャストをしよう System.out.println(((貨幣情報型)(貨幣情報リスト.取得(i))).get貨幣情報ID()); キャスト オブジェクト型のイン スタンスを取り出す 取り出したオブジェクト型のインスタンスを 貨幣情報型にキャストして 貨幣情報型のインスタンスとして扱う 継承とキャスト スーパークラスのインスタンスとして 扱っていた サブクラスのインスタンスを元通り サブクラスのインスタンスとして扱う キャストは一度抽象化したインスタンスを 具象化して使うこと キャストの注意 あるクラスのインスタンスを 別の間違ったクラスのインスタンスに キャストしようとすると・・・・・ 実行時にClassCastExceptionがでます。 コンパイルエラーはでないので注意しましょう まとめ •クラスをさらに抽象化してあつかうことで 効率のよいプログラムを書くことができる •抽象化したインスタンスをもう一度 具体化して扱うためにはキャストが必要 今週の課題 配布したプログラムに次の変更を加えてください 1,商品を追加()メソッドを改良して 追加しようとした商品の商品情報IDが 追加済みの商品情報のIDと同じだったときに 商品の追加をせずにエラーメッセージを表示するように 変更してください 2,取扱商品と取扱貨幣に最後に追加した商品/貨幣情報を 削除するメソッドを追加してください
© Copyright 2024 ExpyDoc