クラスの宣言について

解決


Hero  2006-06-08 00:01:44  No: 131750

VB6ユーザの初心者です。宜しくお願い致します。

現在、クラスについて勉強しておりますが、以下ご教授願えませんでしょうか?

メインフォームにて2つのクラスA,Bを宣言し、
Private clsA As ClassA
Private clsB As ClassB

Set clsA = New ClassA
Set clsB = New ClassB

次にそのクラスAの中で
クラスBを呼び出したい場合、再び、クラスBの宣言をしてやらなければ
ならないのでしょうか?

Private clsB As ClassB

Set clsB = New ClassB

宣言しないでクラスBを呼び出そうとすると「変数が定義されていません。」
というエラーになってしまいます。
クラスの中だけでなくて、異なるフォームにおいても同じです。
何とか一箇所だけで宣言を済ませる方法はありませんでしょうか?

以上、宜しくお願い致します。


魔界の仮面弁士  2006-06-08 00:37:26  No: 131751

> 次にそのクラスAの中でクラスBを呼び出したい場合、
そのような場合には、クラス A のメソッド引数、あるいはプロパティなどに、
B のオブジェクトを渡しておくと良いでしょう。

たとえば「ADO」などでは、そのような作りになっていますね。
  Set C = New ADODB.Connection   '「クラスA」の作成
  C.Open Text1.Text
  Set R = New ADODB.Recordset    '「クラスB」の作成
  Set R.ActiveConnection = C     'A のプロパティにて、B を渡す

あるいは、フォームの Show メソッドも、引数でオブジェクトを渡せる仕様です。
  Form2.Show vbModeless, Me   '「Form2」に、自分(Form1)を渡す


Hero  2006-06-08 18:01:52  No: 131752

魔界の仮面弁士さん
ありがとうございます。

もう少し教えて頂きたいのですが、
>そのような場合には、クラス A のメソッド引数、あるいはプロパティなどに、
>B のオブジェクトを渡しておくと良いでしょう。

私の書いた例で置き換えますと以下の様になるのでしょうか?

Private clsA As ClassA
Private clsB As ClassB

Set clsA = New ClassA
Set clsB = New ClassB
Set clsA.Method = clsB  ?  それとも  Set clsB.Method = clsA  ?(例の通りだとするとこっちですかね?)

宜しくお願い致します。


ガッ  2006-06-08 18:42:43  No: 131753

横から失礼します

> >そのような場合には、クラス A のメソッド引数、あるいはプロパティなどに、
> >B のオブジェクトを渡しておくと良いでしょう。

> 私の書いた例で置き換えますと以下の様になるのでしょうか?

> Private clsA As ClassA
> Private clsB As ClassB

> Set clsA = New ClassA
> Set clsB = New ClassB
> Set clsA.Method = clsB  ?  それとも  Set clsB.Method = clsA  ?(例の通りだとするとこっちですかね?)
えーと

-*-*-*-*-*-*-*-*-
'実行元
sub Hoge()
dim insA as ClassA
call insA.SetInnerClassB(new ClassB)
end sub

-*-*-*-*-*-*-*-*-
'ClassA
private insB As ClassB
public sub SetInnerClassB(byval clsB as ClassB)
set insB=clsB
end sub

-*-*-*-*-*-*-*-*-
'ClassB
'空

-*-*-*-*-*-*-*-*-
のような感じだと思います


魔界の仮面弁士  2006-06-08 18:52:10  No: 131754

> Set clsA.Method = clsB
本題からは外れますが、ここで「Method」という名前が来るのは奇妙かも。
代入式の左辺に使えるのは、メソッドではなく、プロパティや変数ですから。
# かといって、[Property]という名前も問題ありますけどね。(予約語なので)

> 例の通りだとするとこっちですかね?
今回の場合、『クラスAの中で、クラスBを呼び出したい』との事でしたよね。

A が B を呼び出すためには、「A が B の存在を知っていなければならない」わけですから、
すなわち呼び出し側は、「A に B の存在を教えてやる必要がある」という事になります。

ですから、それをプロパティとして渡すのであれば、
  Set clsA.Member = clsB
のように書く事になるでしょう。もしくは、
  Call clsA.Init(clsB)
のように、メソッドの引数として渡す方法もあるでしょう。

この場合、ClassA の方では、
  Private mClass As ClassB
  Public Property Set Member(ByVal NewItem As ClassB)
    Set mClass = NewItem
  End Property
あるいは、
  Private Sub Init(ByVal NewItem As ClassB)
    Set mClass = NewItem
  End Sub
といったプロシージャを用意しておくことになります。

そして、『クラスAの中で、クラスBを呼び出』す際には、
この mClass 変数を使ってアクセスしてやれば OK でしょう。


Hero  2006-06-08 22:40:48  No: 131755

魔界の仮面弁士さん
またまた、ありがとうございます。

ご指摘の本題ではない方なのですが、メソッドとプロパティを使用する場合は、
呼び出し方が異なるのでしょうか?

通常ではない書き方かもしれませんが、いろいろなところを見ていると、メソッドもプロパティも
ClassName.MethodName とか ClassName.PropertyName のように書かれています。
アドバイスを頂いた通り、
プロパティを呼び出す際は、Set を使用し、
Set clsA.Member = clsB  とし、
メソッドを呼び出す場合は、Callを使用し、
Call clsA.Init(clsB)  とするのが本来なのでしょうか?

なんかますます分からなくなってきてしまいました。

クラスからクラスを呼び出すのは、なんとなく分かったような分かったような気がします。
魔界の仮面弁士さんのアドバイスを元にもう少し分で紐解いてみたいと思います。

よろしくお願い致します。


魔界の仮面弁士  2006-06-08 23:46:39  No: 131756

> ご指摘の本題ではない方なのですが、メソッドとプロパティを使用する場合は、
> 呼び出し方が異なるのでしょうか?

たとえば、チェックボックスの『Value プロパティ』は、
    Check1.Value = vbChecked
    Check2.Value = vbGrayed
    Check3.Value = vbUnchecked
のように、『代入式の「左辺」』に配置して、値を「設定」する事ができます。

しかしメソッドは、こういった値の「設定」には使えませんので、
『代入式の「左辺」』に来る事は、基本的にはありません。

> ClassName.MethodName とか ClassName.PropertyName のように書かれています。
(この場合は、クラスではなくオブジェクトかな…)

> プロパティを呼び出す際は、Set を使用し、
> Set clsA.Member = clsB  とし、
プロパティ操作に、常に Set を使うというわけではありません。

Set を使う必要がある(使わなければならない)のは、設定/取得する対象が
「オブジェクト」である場合です。今回の場合、設定する対象が clsB という
オブジェクト変数だったので、Set を付ける事になりますね。

逆に、Set を使ってはいけないのは、それが「オブジェクト以外」の場合です。
たとえば、TextBox の Text プロパティから文字列を「取得」する際には、
  strMessage = Text1.Text
のように書けますし、逆に新しい文字列を「設定」する場合には、
  Text1.Text = "新しい文字列"
のように書きますよね。
文字列はオブジェクトではありませんので、この場合は、Text プロパティの操作に
Set というキーワードは使われません。(Set ではなく Let を使う事ならばありますけど)

> メソッドを呼び出す場合は、Callを使用し、
> Call clsA.Init(clsB)  とするのが本来なのでしょうか?
Call を使うかどうかは任意です。呼び出し側の記述としては、
「Call clsA.Init(clsB)」とも「clsA.Init cls」とも書けますよ。

(1) 戻り値を返さないメソッドの場合
  (1.1) 書き方 その1
    obj.MethodX                    '引数なし
    obj.MethodY 引数1              '引数1個
    obj.MethodZ 引数1, 引数2       '引数2個

  (1.2) 書き方 その2
    Call obj.MethodX               '引数なし
    Call obj.MethodY(引数1)        '引数1個
    Call obj.MethodZ(引数1, 引数2) '引数2個

(2) 戻り値として、数値や文字列などを返すメソッドの場合
  (2.1) 戻り値を取得する必要が無い場合の書き方、その1
    obj.MethodA                    '引数なし
    obj.MethodB 引数1              '引数1個
    obj.MethodC 引数1, 引数2       '引数2個

  (2.2) 戻り値を取得する必要が無い場合の書き方、その2
    Call obj.MethodA               '引数なし
    Call obj.MethodB(引数1)        '引数1個
    Call obj.MethodC(引数1, 引数2) '引数2個

  (2.3) 戻り値を変数に受け取る場合の書き方
    retValue = obj.MethodA()  '引数なし
    retValue = obj.MethodB(引数1)  '引数1個
    retValue = obj.MethodC(引数1, 引数2)  '引数2個

(3) 戻り値として、オブジェクトを返すメソッドの場合
  (3.1) 戻り値を取得する必要が無い場合の書き方、その1
    obj.Method1                    '引数なし
    obj.Method2 引数1              '引数1個
    obj.Method3 引数1, 引数2       '引数2個

  (3.2) 戻り値を取得する必要が無い場合の書き方、その2
    Call obj.Method1               '引数なし
    Call obj.Method2(引数1)        '引数1個
    Call obj.Method3(引数1, 引数2) '引数2個

  (3.3) 戻り値を変数に受け取る場合の書き方
    Set retItem = obj.Method1()             '引数なし
    Set retItem = obj.Method2(引数1)        '引数1個
    Set retItem = obj.Method3(引数1, 引数2) '引数2個

> なんかますます分からなくなってきてしまいました。
ご、ごめんなさい。かえって混乱させてしまったようで……。


Hero  2006-06-09 04:00:38  No: 131757

魔界の仮面弁士様
本当にご丁寧にありがとうございます。

>> なんかますます分からなくなってきてしまいました。
>ご、ごめんなさい。かえって混乱させてしまったようで……。

とんでもないです。こちらこそ頭が上がりません。
今回のレスで”クラスへの道”がかなり明るくなってまいりました。
今回のアドバイスを元に精進して参ります。
また、何かありましたら、よろしくお願い致します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加