Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3176 / 13644 ツリー ←次へ | 前へ→

【63733】VBAにおけるクラスの擬似承継 みそじのおじさん 09/12/4(金) 18:13 質問[未読]
【63734】1だけ YU-TANG 09/12/5(土) 20:30 回答[未読]
【63738】Re:1だけ みそじのおじさん 09/12/6(日) 13:30 お礼[未読]

【63733】VBAにおけるクラスの擬似承継
質問  みそじのおじさん  - 09/12/4(金) 18:13 -

引用なし
パスワード
   毎度お世話になっております。

現在VBAにおけるクラスの擬似承継について勉強をしております。

私は普段、ゲームのたぐいはほとんどしないのですが、たとえがわかり易く
なると思いドラクエにでてきそうな敵のクラスを作成してみました。

標準モジュール
Option Explicit

Sub Main()

  Dim Enemy As clsChird
  '子クラスのインスタンスの作成
  Set Enemy = New clsChird
 
  '自分の体力を回復する魔法を使用
  Enemy.MAGIC
 
  '体力を表示
  Debug.Print "Enemy HP =" & Enemy.HP

  '相手にあたえるダメージを表示 
  Debug.Print "Enemy Attack =" & Enemy.ATTACK
 
  Set Enemy = Nothing

End Sub

クラスモジュール1

Option Explicit

'////////////////////////////////////////////////////////
'クラス名 clsParent (親クラス)
'説明   敵のクラス
'特徴   攻撃はできないが、自分の体力を回復する魔法を
'     使う事ができる。
'////////////////////////////////////////////////////////

Private mMP As Long 'マジックポイント
Private mHP As Long '体力

Private Sub Class_Initialize()
  mHP = 20 '体力を20に設定
  mMP = 10 'マジックポイントを20に設定
End Sub

Property Get HP() As Long
  HP = mHP
End Property

Property Get MP() As Long
  MP = mMP
End Property
'自身の体力を+5回復する
Public Sub MAGIC()
  mHP = mHP + 5
End Sub

クラスモジュール2
Option Explicit
'////////////////////////////////////////////////////////
'クラス名 clsChird (子クラス)
'説明   敵のクラス
'特徴   親クラスの特徴を承継して、さらに子クラス独自の
     メソッド、プロパティを実装する。
     このクラスでは親クラスと同じ魔法が使用できて
     さらに相手を攻撃する事ができる。
     HP,MPは親クラスと同じ
'////////////////////////////////////////////////////////
Private mParent As clsParent
Private mMP As Long
Private mHP As Long

Private Sub Class_Initialize()
 '子クラス内に親クラスのインスタンスの作成
 Set mParent = New clsParent
End Sub

Private Sub Class_Terminate()
 Set mParent = Nothing
End Sub

Property Get MP() As Long
  '親クラスのプロパティ呼び出し
  mMP = mPaprent.MP
  MP = mMP
End Property

Property Get HP() As Long
  '親クラスのプロパティ呼び出し
  mHP = mParent.HP
  HP = mHP
End Property

Public Sub MAGIC()
  '親クラスのメソッド呼び出し
  mParent.MAGIC
End Sub

'相手に与えるダメージ量をランダム値で返す。
Public Function ATTACK() As Integer
 
 Randomize
 
  ATTACK = CInt((10 - 1) * Rnd + 1)
 
End Function


1 擬似的にクラスを承継したいが為に、
 子クラス内に使用したい親クラスのメソッド、プロパティを
 全て書いていますが、他の実現方法がありますでしょうか?
 (現状ですと、親クラスに変更、追加があった場合に関係する
  全ての子クラスを修正しなければいけません。)

2 最近私は、Scripting.Dictionaryの主要な機能をラッパーして
 さらに独自の機能を追加したクラスを作成しました。
 
 付けた機能は、
 myDic.Sort "ASC" myDic.Sort "DESC" などと書き
 keyを昇順、降順にSortしたり(Itemも)
 (keyが数値という制限がありますが)

 myDic.KeyValue(Index)みたく書き、Keyの配列内でのインデック
 ス値でKeyの値を参照するプロパティを付けたりしてみました。
 
 CreateObjectを使用するとインテリジェンス機能が使えなくなる
 というのもあり、一度クラスを作成してしまえば、使いまわしが
 よく自分の中では大変重宝しております。
 
 みなさまがお使いの「これは一度作れば非常に便利!!」という
 クラスを教えて頂けないでしょうか?(ソース抜きだと非常に
 ありがたいです。自分への作成課題にしたいので)

勉強の為にやっておりますので、まったく急いでおりません。
1または2の質問だけでもかまいませんので
お時間のある時にでもよろしくお願い致します。

【63734】1だけ
回答  YU-TANG  - 09/12/5(土) 20:30 -

引用なし
パスワード
   こんばんは、YU-TANG です。

1 だけ。

> 1 擬似的にクラスを承継したいが為に、
>  子クラス内に使用したい親クラスのメソッド、プロパティを
>  全て書いていますが、他の実現方法がありますでしょうか?
>  (現状ですと、親クラスに変更、追加があった場合に関係する
>   全ての子クラスを修正しなければいけません。)

残念ながら、VBA では実現できません。
VB.NET のようなオブジェクト指向言語を使うしかないでしょう。

ただ、継承と関係ない使い方として、あるクラス foo に手を入れずに
特定の機能群を拡張可能にしたい場合は、それらをまとめたクラス bar
のインスタンス自体をプロパティとして公開してしまう方法が有ります。
この場合は、クラス bar を拡張しても、クラス foo を変更する必要は
ありません。その代わり、呼び出し方は foo.bar.hoge() のような
形になりますが。

あと、ご提示のコードでは、実際の継承は行われていませんね。
clsParent と clsChird のあいだには、何の関係性もありません。
たまたまメンバが同じ名前というだけで、独立したクラスです。
VBA には VBA で、ちゃんと継承の仕組みがあります。
もしかしたらご存知の上であえて使っていないだけかもしれません
が、Implements ステートメントをヘルプで調べてみてください。
Implements ステートメントはインターフェイスを継承するだけ
なので、実装は結局クラス個別に行う必要があります。とは言え、
インターフェイスが継承される (型が強制される) ことだけでも、
多態性の観点からは非常に大きな意味がありますが。

それでは。

【63738】Re:1だけ
お礼  みそじのおじさん  - 09/12/6(日) 13:30 -

引用なし
パスワード
   ▼YU-TANG さん:
レスありがとうございます。
返事が遅れ申し訳ありません。忘年会の二日酔いにやられていました。

>残念ながら、VBA では実現できません。
>VB.NET のようなオブジェクト指向言語を使うしかないでしょう。

これは承知しておりました。

>ただ、継承と関係ない使い方として、あるクラス foo に手を入れずに
>特定の機能群を拡張可能にしたい場合は、それらをまとめたクラス bar
>のインスタンス自体をプロパティとして公開してしまう方法が有ります。
>この場合は、クラス bar を拡張しても、クラス foo を変更する必要は
>ありません。その代わり、呼び出し方は foo.bar.hoge() のような
>形になりますが。

なるほど、非常に参考になります。
「インスタンス自体をプロパティとして公開してしまう方法」
これがみそなんですね。

>もしかしたらご存知の上であえて使っていないだけかもしれません
>が、Implements ステートメントをヘルプで調べてみてください。

はずかしながら、こちらは知りませんでした。
じっくり調べてみたいと思います。

クラスを作成する意義、カプセル化、ポリモーフィズムなどの概念は
理解しているつもりでしたが、いざ実装となった時に、ここはどうする?
あーここはだめだとクラス作成の経験不足があちこちに出てきてしまいます。

特に、ichinoseさんがこのサイトで何年か前に、
「モジュール間の結合度が強すぎる」と書かれていた事があってその当時
強い衝撃を受けました。(まさに自分のコードがそれそのものだったので)

 それから結合度という言葉を意識しながらコーディングしているつもり
なのですが、出来上がる物は残念ながら汎用性のない物になることが
多々あります。まだまだ修行がたりませんね。^^

YU-TANGさんとても参考になりました。ありがとうございました。

3176 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free