- PR -

サーブレット内の動作について

1
投稿者投稿内容
tahakoda
ベテラン
会議室デビュー日: 2002/08/17
投稿数: 79
投稿日時: 2002-08-17 00:39
初めて投稿させて頂きます。経験が浅いもので質問がうまく伝わるか自信がありませんが宜しくお願いします。
現在、某雑誌掲載のサンプルを基にServletの独学をしています。実はサンプル内のソースについて疑問がありましてご質問したいのです。

サンプルは簡単なショッピングサイトでServlet起動時に「魚屋」と「果物屋」の2つの店(Shop)を作成し各店に3つの商品の一覧(showcase)を持たせるというものです。

Main.javaはServletで起動処理時にShopクラスのインスタンスを作成します。その際Shopクラスはコンストラクタからの戻り値としてShowCaseを受け取りShowCaseの親クラスのメソッドを使用して商品を追加していきます。しかしここからわからない点があります。

まずinit()内で宣言したshowcaseを「fishShop.getShowCase()」と「fruitsShop.getShowCase()」とで使い回している点です。「魚屋」の商品を「果物屋」で上書きしているように思えるのですが。。。解釈が間違っていますでしょうか?。

またお恥ずかしい話ですが「showcase.addItem」で保存された商品一覧がどのようにして各Shopに保持されているのか技術的にわかりません(各商品がVectorに保存される所まではわかるのですが・・)。
具体的にはお店から買い物かごに入れる際「shop.getShowCase().getItem(id)」とServletのdoGet()にはありますが、この「getShowCase()」で何故商品の一覧が取得できるのかがわからないのです。おそらくinit()内で実行した操作と関連があるとは思いますが。。。

自身がJAVAの理解が足りないため説明があやふやかもしれませんが良きアドバイスを頂けましたら幸いです。下記にサンプルを掲載します。宜しくお願いします。(長くなりすみません。。)

-- Main.java
public class Main extends HttpServlet{
private Shop fishShop;
private Shop fruitsShop;

public void init() throws ServletException{
ShowCase showcase;
fishShop = new Shop("魚屋");
showcase = fishShop.getShowCase();
showcase.addItem(1,"さんま",200);
showcase.addItem(2,"いわし",100);
showcase.addItem(3,"かれい",300);

fruitsShop = new Shop("果物屋");
showcase = fruitsShop.getShowCase();
showcase.addItem(1,"りんご",200);
showcase.addItem(2,"ばなな",100);
showcase.addItem(3,"みかん",300);
}

public void doGet(HttpServletRequest request・・・){


if(request.getParameter("fishShop") != null) {
/* 魚屋の画面に遷移する*/
session.setAttribute("shop", fishShop);
getServletContext().getRequestDispatcher("/Cart.jsp").forward(request, response);


/* お店から指定商品を買い物かごへ入れる */
Shop shop = (Shop)session.getAttribute("shop");
int id = Integer.parseInt(request.getParameter("addItem")); //商品番号
Item item = shop.getShowCase().getItem(id);


}
}

-- Shop.java
public class Shop {
private String name;
private ShowCase showcase;

public Shop(String name){
this.name = name;
showcase = new ShowCase();
}
public String getName(){
return name;
}
public ShowCase getShowCase(){
return showcase;
}
}

-- ShowCase.java
public class ShowCase extends Items{
public ShowCase(){}
}

-- Items.java
import java.util.Vector;
public class Items{
private Vector items;
public Items(){
items = new Vector();
}
public void addItem(int id, String name, double price){
addItem(new Item(id, name, price));
}
public void addItem(Item item){
items.addElement(item);
}
public Item getItemByIndex(int index){
return (Item)items.get(index);
}
public Item getItem(int id){
Item item = null;
for(int i = 0; i < items.size(); i++){
item = getItemByIndex(i);
if(item.getId() == id){
return item;
}
}
return null;
}
}
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-08-17 12:19
二重にスレッドをたてるのは止めましょう!

>まずinit()内で宣言したshowcaseを「fishShop.getShowCase()」と
>「fruitsShop.getShowCase()」とで使い回している点です。「魚屋」の商品を「果物屋」で
>上書きしているように思えるのですが。。。解釈が間違っていますでしょうか?。
この場合、上書きにはなりません。変数の使い回しをしているだけです。
コード:
 fishShop = new Shop("魚屋");
fishShop.getShowCase().addItem(1,"さんま",200);
fishShop.getShowCase().addItem(2,"いわし",100);
fishShop.getShowCase().addItem(3,"かれい",300);

fruitsShop = new Shop("果物屋");
fruitsShop.getShowCase().addItem(1,"りんご",200);
fruitsShop.getShowCase().addItem(2,"ばなな",100);
fruitsShop.getShowCase().addItem(3,"みかん",300); 


と書いても同じ処理をします。

>この「getShowCase()」で何故商品の一覧が取得できるのかがわからないのです。
"getShowCase()"で商品の一覧が取得できるわけではありません。
"getShowCase()"で取得できるのはShowCaseオブジェクトです。
"ShowCaseオブジェクト=商品の一覧"という考え方もあるかもしれませんが、
それならShop.javaを理解していればわかるはずです。

----------
基礎をきちんと勉強してから応用に挑みましょう。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2002-08-17 14:14
引用:

まずinit()内で宣言したshowcaseを「fishShop.getShowCase()」と「fruitsShop.getShowCase()」とで使い回している点です。「魚屋」の商品を「果物屋」で上書きしているように思えるのですが。。。解釈が間違っていますでしょうか?


確かに、上書きはしています。が、『「魚屋」の商品を「果物屋」で上書きしている』わけではありません。『「魚屋」オブジェクトを参照していた変数を、「果物屋」オブジェクトを参照する』ようにしているだけです。

この辺はプログラミングをするのに非常に大事なので、しっかりと身につけることが大事ですので参考書などを読んで勉強することをお勧めします。

ちょこっとだけ説明しますが、これを読んで分かっても、分からなくても参考書を読んで理解してください。

Javaには2種類の変数があります。プリミティブタイプと参照タイプです。boolean, int, double, float, charなどの変数はプリミティブタイプと言われます。Object, String, Shop, ShowCaseなどの new する変数は参照タイプになります。

プリミティブタイプの変数は、変数が「値」を保持します。変数numberが1という数字を保持している場合、変数numberが1という「値」を持っていることになります。(分かりますよね)ですので、上書きをすると前に保持していた値はきれいさっぱりなくなって、新しい値に変わります。numberが上書きされて4という値を持つと、前に持っていた1という「値」は消え去ります。
コード:
int i = 3;  //i には 3 という値が格納される。
  ・・・
i = 4       //i には 4 という値が上書きされる。3という数字は消え去る。



参照タイプの変数は、変数がオブジェクトに対する「参照値」を保持します。「参照値」はメモリ上の住所だとでも思ってください。オブジェクトは必ずメモリ上にないといけません。参照タイプの変数は、参照しているオブジェクトへの道しるべのようなものです。

個々のオブジェクトにアクセスするには変数に格納されているこの道しるべともいえる「参照値」を使うことになります。もし、これらの変数が上書きされると、道しるべは別のオブジェクトを指します。でも、前に指していたオブジェクトは消えたわけでありません。まだしっかりとメモリ上に残っています。

コード:
ShowCase showcase = fishShop.getShowCase();  
                //showcaseにはfishShopの持っているShowCaseに対する参照が格納される。
  ・・・
showcase = fruitsShop.getShowCase(); 
                //showcaseにはfruitsShopの持っているShowCaseに対する参照が格納される。
                //ここで大事なのは、「fishShopの持っているShowCaseに対する参照」は
                //なくなったが、「fishShopの持っているShowCase」自体はまだメモリ上に
                //残っているので消えたわけではない。



まとめ:
プリミティブタイプの変数では「値」が保持される。変数に上書きすると前に保持していた値はきれいになくなる。
参照タイプの変数では「個々のオブジェクトへの参照値」が保持される。変数を上書きしても、「参照値」が変わるだけなので、個々のオブジェクトは上書きされない。

引用:

またお恥ずかしい話ですが「showcase.addItem」で保存された商品一覧がどのようにして各Shopに保持されているのか技術的にわかりません


各ShopはそれぞれShowCaseを持っています。ShowCaseはItemsという型を継承しているので、ItemsのVectorに商品情報を格納しているだけです。

これもJavaやオブジェクト指向の言語では大事なので、しっかりと参考書を読んで勉強することをお勧めします。幸いにも「技術的に分からない」と知っているのですから、あとは勉強するだけです。(「分からない」と知る事って以外にも難しいものです

Servletをはじめる前に、Javaの基礎を押さえると上達が早くなります。急がば回れということわざがあるように、ちょっと回り道をした方が結果的には早いですよ。
tahakoda
ベテラン
会議室デビュー日: 2002/08/17
投稿数: 79
投稿日時: 2002-08-19 16:28
ご返事が遅れ大変失礼しました。
Javaの基本事項を詳細にご説明して頂き本当にありがとうございました。
もう一度基本から学び直しチャレンジしてみます。
1

スキルアップ/キャリアアップ(JOB@IT)