- PR -

共有オブジェクト

1
投稿者投稿内容
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2004-05-28 15:19
こんにちわ。

すごく基本的なことかもしれませんが
パニくってきました。

[登場人物]
 ModelA:単純なオブジェクト ModelBと同じ親クラスを持ちextendsしている
 ModelB:単純なオブジェクト ModelAと同じ親クラスを持ちextendsしている
 Factory:ModelA,Bを保持する。正確にはAbstractModelを保持
 A、B:タスク。スレッド

1.FactoryにModelA型をセット

2.AはFacotryからmodelを取得
  AbstractModel model = getModel() ← ModelA型を取得

3.BはFacotryからmodelを取得
  AbstractModel model = getModel() ← ModelA型を取得

4.AはFactoryにmodelを設定
  setModel( modelB ) ← ModelB型を設定

5.Bが所有しているmodelは何型?

要は参照の考えがいまひとつわかってないような
気がするんですが、5.のmodelはModelA型が正解
かと思います。

しかしながら、なぜModelB型でないのかパニくって
きました。
ModelA型であっても、ModelA.XXX()など、なぜ
ModelAのメソッドが呼べたりするのかわからないです。
なぜNoSuchMethodErrorとかにならないんでしょうか。

A,B両者が2.3.で取得する参照先は同一だと
思います。4.においてModelBを設定することで
Bが持つmodelの参照先はModelBにはならないんでしょうか。

Javaのオブジェクトは「参照のの値渡しである」というのは
なんとなく理解しているつもりなのですが、よくわかって
いないのも事実です。

その辺でコケている?
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-05-28 16:36
この説明を読んでいて困惑するのは
・Factory というのは Factory パターンを意味するのか?(たぶん意味しない)
・ModelA と A、ModelB と B の関係って?(多分関係ない)
・タスク、スレッドって?
・型って? インスタンスじゃなくて?
といったところです。私の理解が間違っていたらここらへんをもう少し説明していただけるとうれしいです。

で、説明を理解できたか自信ありませんが、恐らく、

2.でFactory が保持しているのは最初は ModelA型
3.の時点でA と B が保持しているのは ModelA 型
4.でFactory が保持しているのは ModelB 型
5.で B が保持しているのは ModelA 型
です。
Bが保持しているのは "Factoryが参照している Model" という情報ではなくて純粋に ModelA への参照ですから。
Factory や A から積極的に B に対して参照先を変更するような作業をしなければ B の参照先は変わりません。
また、3.の時点でA と B が保持しているのは同じ ModelA型(のインスタンス?)です。
Aが ModelA に対してなんらかの操作をすればその変更内容は B からも参照できます。

>ModelA型であっても、ModelA.XXX()など、なぜ
>ModelAのメソッドが呼べたりするのかわからないです。
>なぜNoSuchMethodErrorとかにならないんでしょうか。
これはまた別の次元になりますのでよく整理してわかんなかったらスレッド立ててみてください。

>Javaのオブジェクトは「参照のの値渡しである」というのは
一般に、「参照渡し」と「値渡し」ってのを区別します。
Java では同一 JVM 内であれば参照渡しで、リモート呼び出しであれば値渡しになります。
でも今回の話題は参照渡しか値渡しかどうかは関係ないですよね・・・。どちらでも同じ結果になると思います。

[ メッセージ編集済み 編集者: インギ 編集日時 2004-05-28 16:41 ]

[ メッセージ編集済み 編集者: インギ 編集日時 2004-05-28 16:45 ]
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2004-05-28 17:05
インギさんありがとうございます。

サンプルで作っていたのは以下のような感じでした。
スレッドうんたらとか簡略化してるのでわかりづらい
ですが、やってることは下と同じですね。

コード:
Main
---
public class Main {

    public static void main(String[] args) {
        ModelA a = new ModelA( new Integer(10) );
        ModelB b = new ModelB( "name" );
		
        ModelFactory factory = ModelFactory.getInstance();
        factory.setModel( a );
		
        ModelA m = (ModelA) factory.getModel();
		
        factory.setModel( b );

    // mの参照先って??
    }
}

AbstractModel
---
public abstract class AbstractModel {
}

ModelA
---
public class ModelA extends AbstractModel {
    private Integer age;
	
    public ModelA( Integer age ) {
    	this.age = age;
    }
    
    public Integer getAge() {
        return age;
    }

    public void setAge( Integer integer ) {
        age = integer;
    }
}

ModelB
---
public class ModelB extends AbstractModel {
    private String name;
	
    public ModelB( String name ) {
    	this.name = name;
    }
    
    public String getName() {
        return name;
    }

    public void setName( String string ) {
        name = string;
    }
}

ModelFactory
---
public class ModelFactory {
    private static ModelFactory factory;
    private AbstractModel model;
	
    private ModelFactory() {}
	
    public static synchronized ModelFactory getInstance() {
        if ( factory == null ) factory = new ModelFactory();
        return factory;
    }
	
    public AbstractModel getModel() {
        return model;
    }

    public void setModel( AbstractModel model ) {
        this.model = model;
    }
}



とりあえず、これだけ載せておきます。
インギさんの回答については、今からまたじっくり考えてみます。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2004-05-28 17:12
>Bが保持しているのは "Factoryが参照している Model"
>という情報ではなくて純粋に ModelA への参照ですから。

わかりました・・。

なるほど。
私が提示したコードで言うと

Mainの
ModelA m = (ModelA) factory.getModel();

という箇所で取得したインスタンスの参照先は

同じくMainの
ModelA a = new ModelA( new Integer(10) );
であって
Factoryが保持しているmodelの参照先ではない
ということですね。

うーむ。なるほど。

基本的なことだと思いますが、お付き合い頂き
ありがとうございました。
アティ
ベテラン
会議室デビュー日: 2003/08/14
投稿数: 91
お住まい・勤務地: KANAGAWA
投稿日時: 2004-05-28 21:34
なんか分かってないような気が...
抽象的に言いますね。
まず、factory、a、bっていう物体(Object)があると思ってください。
(作る作業は、
コード:
	ModelA a = new ModelA( new Integer(10) );
	ModelB b = new ModelB( "name" );

	ModelFactory factory = ModelFactory.getInstance();


)
factoryには、modelというアンカー(紐を止めるところ)があると思ってください。
そして、
コード:
factory.setModel( a );


で、
modelアンカーとa物体を紐で結ぶんです。参照は、紐で結ぶことだと思ってください。
だから、
コード:
	ModelA m = (ModelA) factory.getModel();


で、modelアンカーについてる紐を辿った物体とmというアンカーを紐で結びつけるんです。
コード:
	factory.setModel( b );


これで、factoryのmodelアンカーと物体aを結んである紐を、物体bと結びます。
でも、mと結んだ紐は元のままなので、物体aと繋がっているわけです。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2004-05-31 11:52
アティさん

ありがとうございます。

その説明で言うと、私はmと紐づいている先を
factoryのmodelアンカーだと思ってしまったの
が間違いだったという認識をしています。

正確にはmと紐づいているのはaであると理解
しました。
1

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