クラスをクラスのフィールドにする

クラスをクラスのフィールドにする

クラスを丸ごとクラスのフィールドにしたらいいんじゃないか、と今さらながらに気がついた。Javaの本でさんざん目にしていたことなんだけど。

フィールド用のクラス

「GambleRacer」というクラスを作った。

クラスモジュールのコード

Option Explicit
'フィールド
Private name_ As String
Private racingStyle_ As String
Private racingPoints_ As Integer
'アクセサ
Public Property Get name() As String
  name = name_
End Property
Public Property Get racingStyle() As String
  racingStyle = racingStyle_
End Property
Public Property Get racingPoints() As Integer
  racingPoints = racingPoints_
End Property
'コンストラクタ

'メソッド
Public Sub setData(ByVal n As String, _
                   ByVal rs As String, _
                   ByVal rp As Integer)
  name_ = n
  racingStyle_ = rs
  racingPoints_ = rp
  MsgBox "データをセットしました。"
End Sub

Public Sub showMyself()
  MsgBox "私は" & name_ & "です。" & vbCrLf & _
         "得意戦法は" & racingStyle_ & "、" & vbCrLf & _
         "競走得点は" & racingPoints_ & "点です。"
End Sub

フィールドとして名前、戦法、競走得点の3つを持ち、メソッドとしてデータをセットするsetDataと、自己紹介をするshowMyselfの2つを持つクラス。

GambleRacerをフィールドに持つクラス

「KeirinRace」というクラスを作った。

クラスモジュールのコード

Option Explicit
'フィールド
Private gr_ As GambleRacer
'アクセサ
Public Property Get gr() As GambleRacer
  Set gr = gr_
End Property
'コンストラクタ

'メソッド
Public Sub setData(ByRef gr As GambleRacer)
  Set gr_ = gr
End Sub
Public Sub doKeirin()
  With gr_
    MsgBox .name & "の" & "渾身の" & .racingStyle & "が決まった!" & vbCrLf & _
           "さすが" & .racingPoints & "点レーサー!"
  End With
End Sub

フィールドとしてGambleRacerクラスを持ち、データをセットするsetDataと、競輪競走を行う(笑)doKeirinという2つのメソッドを持つクラスにした。

実行

標準モジュールに次のコードを書いて実行してみた。

標準モジュールのコード

Sub test()
  Dim kr As KeirinRace                 '……(1)'
  Set kr = New KeirinRace              '……(2)'
  Dim gr As GambleRacer                '……(3)'
  Set gr = New GambleRacer             '……(4)'
  gr.setData "中野 浩一", "捲り", 120  '……(5)'
  gr.showMyself                        '……(6)'
  kr.setData gr                        '……(7)'
  kr.doKeirin                          '……(8)'
  Set gr = Nothing
  Set kr = Nothing
End Sub

コードの説明

説明することに意義があるかどうかは不明なれど……。

  • (1)でKeirinRaceクラスの変数を準備。
  • (2)でKeirinRaceクラスのインスタンスを生成。
  • (3)でGambleRacerクラスの変数を準備。
  • (4)でGambleRacerクラスのインスタンスを生成。
  • (5)で、GambleRacerクラスのsetDataメソッドを用いて各データをセット。こんなの、本来コンストラクタでやることですが。
  • (6)で、GambleRacerクラスのshowMyselfメソッドを用いて自己紹介させる。
  • (7)で、KeirinRaceクラスのsetDataメソッドを用いてデータをセット。引数としてGambleRacerクラスのインスタンスを渡している。
  • (8)で、KeirinRaceクラスのdoKeirinメソッドを実行。

実行結果

f:id:akashi_keirin:20170321225827j:plain

GambleRacerクラスのsetDataメソッドが実行された証。

f:id:akashi_keirin:20170321225834j:plain

GambleRacerクラスのshowMyselfメソッドが実行された。

f:id:akashi_keirin:20170321225842j:plain

KeirinRaceクラスのdoKeirinメソッドも無事実行された。

おわりに

ちょっと今まで「クラスの独立性」という概念を勘違いしていたのかも。まだまだ勉強が足りませんな。