- PR -

別クラスのメソッドを使用する場合についての質問

投稿者投稿内容
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-11-18 19:18
私の場合、このような事態に陥りそうなとき、FactoryMethodの使用を検討します。

コード:
class Class_A {
  public static Class_A getInstance() {
    Class_A a = new Class_A();
    a.setCLass_B(new Class_B(a));

    return a;
  }

  public void A_Method() {...}
  
  private void setClass_B(Class_B b) {
    ....
  }
  
  private Class_A() {...}
}



taka
常連さん
会議室デビュー日: 2003/09/22
投稿数: 46
投稿日時: 2003-11-19 10:06
かずくんさん、ご意見ありがとうございました。
FactoryMethodに関しての知識が乏しいので、勉強してかずくんさんにいただいたコードを見直そうとおもいます。

ところで、例えば下記のような場合、クラスA、B、Cがあります。
クラスAはクラスBを作成しています。
クラスBはクラスCを作成しています。
クラスCはクラスAのメソッドを実行しています。
クラスCまでが作成された時には、クラスAは全部で3つあると考えるのでしょうか?
一つは元々のクラスA、二つ目はクラスBの中でのクラスA、三つ目はクラスCの中でのクラスA。
もしも、3つあるのだとするとメモリー上にはまったく同じクラスAが3つ存在する事になるのでしょうか?

public class Class_A { //元々のクラスA
 boolean blnA = false;
 void makeClassB(){
  Class_B clsB = new Class_B(this); //クラスB作成
 }
 
 void A_Method(){
  blnA = true;
 }
}

public class Class_B {
 Class_A clsA;//クラスBの中でのクラスA
 public Class_B(Class_A cls) {
  clsA = cls;
 }
 void makeClassC(){
  Class_C clsC = new Class_C(clsA); //クラスC作成
 }
}

public class Class_C {
 Class_A clsA; //クラスCの中でのクラスA
 public Class_C(Class_A cls) {
  clsA = cls;
 }

 void doClsAMethod(){
  clsA.Method(); //クラスAのメソッドを実行
 }
}

うーん、説明しながら我ながら良くわからない説明だ・・・・
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-11-19 10:34
unibon です。こんにちわ。

引用:

takaさんの書き込み (2003-11-19 10:06) より:
ところで、例えば下記のような場合、クラスA、B、Cがあります。
クラスAはクラスBを作成しています。
クラスBはクラスCを作成しています。
クラスCはクラスAのメソッドを実行しています。
クラスCまでが作成された時には、クラスAは全部で3つあると考えるのでしょうか?
一つは元々のクラスA、二つ目はクラスBの中でのクラスA、三つ目はクラスCの中でのクラスA。
もしも、3つあるのだとするとメモリー上にはまったく同じクラスAが3つ存在する事になるのでしょうか?


Java はインスタンスを生成するためには必ず new しないといけないので、
ソースコードのエディタ上で new の場所を探したり、
あるいはブレークポイントをしかけたり print 文を追加しておけば、
どれだけのインスタンスが生成されたかは明確に分かります。
#リフレクションが絡むと違うのかな?細かなことは良くは分かりませんが。

提示されたコードだと Class_B の new が1箇所だけ、Class_C の new も1箇所だけであり、
Class_A の new がされている箇所がないので、
厳密に言えば Class_A のインスタンスはひとつもできません。
もちろん、ご説明で暗黙の内に Class_A のインスタンスを
main メソッド内あたりで生成されているのだと思いますが、
もしそれが1回だけの new なら Class_A のインスタンスもひとつだけです。
Class_B や Class_C がフィールドとして持っている Class_A は、
そのひとつのインスタンスを共有しているだけです(分離されていない)。

老婆心ながらサンプルは、
上記のような main メソッド(?)内での new などについても
省かずに提示されるとサンプルが厳密になって良いと思います。
#今のものでも分かりやすい良いサンプルだと思いますが。
ただ、なにをもくろまれているのかが、サンプルからはイマイチ分からないです。
単に、Java におけるクラス間の関係をいろいろ試されているだけなのか、
なにか目的があってこういうことをする必要があるのかの、どちらでしょうか。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-11-19 10:32
unibon です。こんにちわ。

引用:

takaさんの書き込み (2003-11-19 10:06) より:
ところで、例えば下記のような場合、クラスA、B、Cがあります。
クラスAはクラスBを作成しています。
クラスBはクラスCを作成しています。
クラスCはクラスAのメソッドを実行しています。
クラスCまでが作成された時には、クラスAは全部で3つあると考えるのでしょうか?
一つは元々のクラスA、二つ目はクラスBの中でのクラスA、三つ目はクラスCの中でのクラスA。
もしも、3つあるのだとするとメモリー上にはまったく同じクラスAが3つ存在する事になるのでしょうか?


Java はインスタンスを生成するためには必ず new しないといけないので、
ソースコードのエディタ上で new の場所を探したり、
あるいはブレークポイントをしかけたり print 文を追加しておけば、
どれだけのインスタンスが生成されたかは明確に分かります。
#リフレクションが絡むと違うのかな?細かなことは良くは分かりませんが。

提示されたコードだと Class_B の new が1箇所だけ、Class_C の new も1箇所だけであり、
Class_A の new がされている箇所がないので、
厳密に言えば Class_A のインスタンスはひとつもできません。
もちろん、ご説明で暗黙の内に Class_A のインスタンスを
main メソッド内あたりで生成されているのだと思いますが、
もしそれが1回だけの new なら Class_A のインスタンスもひとつだけです。
Class_B や Class_C がフィールドとして持っている Class_A は、
そのひとつのインスタンスを共有しているだけです(分離されていない)。

老婆心ながらサンプルは、
上記のような main メソッド(?)内での new などについても
省かずに提示されるとサンプルが厳密になって良いと思います。
#今のものでも分かりやすい良いサンプルだと思いますが。
ただ、なにをもくろまれているのかが、サンプルからはイマイチ分からないです。
単に、Java におけるクラス間の関係をいろいろ試されているだけなのか、
なにか目的があってこういうことをする必要があるのかの、どちらでしょうか。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2003-11-19 10:37
上記のコードだと、クラスAのオブジェクトは1つしかありません。ただし、クラスAのオブジェクトへの参照は3つあります。

オブジェクトがメモリ上に生成されるのは new Class_A() とした時です。Class_BやClass_C内では new Class_A() という記述がないのでオブジェクトは作られていません。ただし、既に作られているClass_Aのオブジェクトへの「参照」が渡されています。

ここら辺はJavaでは非常に大事です。
アティ
ベテラン
会議室デビュー日: 2003/08/14
投稿数: 91
お住まい・勤務地: KANAGAWA
投稿日時: 2003-11-19 10:48
Javaでは、メソッドの引数は参照渡し(プリミティブ型以外)になるので、上の例だとクラスAは1つだけになります。
参照は、C等のポインタとほぼ同じものと考えればいいと思います。
ポインタとの違いは、ポインタだと「ポインタのポインタ」が出来ますが、
「参照の参照」はできないことだったかな。(他にも違いはあると思いますが)
現実的に言うと、家(Object)を建てて友人には住所(参照)を教えるって感じで(変な例えだ)。
taka
常連さん
会議室デビュー日: 2003/09/22
投稿数: 46
投稿日時: 2003-11-19 10:59
unibonさん、H2さんご意見ありがとうございました。

>ただ、なにをもくろまれているのかが、サンプルからはイマイチ分からないです。
>単に、Java におけるクラス間の関係をいろいろ試されているだけなのか、
>なにか目的があってこういうことをする必要があるのかの、どちらでしょうか。
前者です、クラス間での関係やガベージコレクションを勉強しています。

>上記のコードだと、クラスAのオブジェクトは1つしかありません。
>ただし、クラスAのオブジェクトへの参照は3つあります。
なるほど、"new"してインスタンスしなければ新しくメモリー上に生成されないのですね。
ということは、例えばクラスBを下記のようにした場合("makeClassC() "メソッドに"clsC = null;"の一文を入れました。)
クラスCの中でクラスAを参照している為、クラスBの中の"clsC"がGCによって解放されはしないと考えていいのでしょうか?


public class Class_B {
 Class_A clsA;//クラスBの中でのクラスA
 public Class_B(Class_A cls) {
  clsA = cls;
 }
 void makeClassC(){
  Class_C clsC = new Class_C(clsA); //クラスC作成
  clsC = null;
 }
}

H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2003-11-19 11:16
> クラスCの中でクラスAを参照している為、クラスBの中の"clsC"がGCによって
> 解放されはしないと考えていいのでしょうか?
違います。逆です。clsCが参照していたClass_Cのオブジェクトは clsC=null; でGCによって開放されてしまいます。この時点でclsCが参照していたClass_Cのオブジェクト参照している物が何もないからです。逆に、clsCが参照していたオブジェクトが開放された後でも、clsCが参照していたClass_AのオブジェクトはClass_Bのオブジェクトが参照しているのでまだメモリ上に残ります。

>現実的に言うと、家(Object)を建てて友人には住所(参照)を教えるって感じで(変な例えだ)
面白いですね

[ メッセージ編集済み 編集者: H2 編集日時 2003-11-19 11:26 ]

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