VBAでのInterfaceやキャスト

前段

個人的に、Excel VBAを仕事で組む機会がある。 自由に組んでいるので、いろいろと設計方法、実装方法を考える。

VBAのインターフェース

VBAにはJavaでいうextendsのような継承はない。 Interfaceがあるので、ポリモーフィズムを実現するときは、これを使うのが一つの方法論だ。 ただ、インターフェースは、というか、VBAはクラスのキャストができない。 インターフェイス自体が、そうする性質のものではないのだが、つい欲しくなるときがある。

Object型

さて、話は変わるが、VBAには、Object型というものがある。 平たく言うと、あらゆるクラスに適する型である。あらゆるクラスのスーパークラスと思うと話が早い。
そして、Objcet型からは元のクラスで実装したプロシージャを呼ぶことができる。ObjectによるポリモーフィズムもVBAでは可能、といえる。
なので、ダウンキャストを実現するために、インターフェイスでインスタンスが自己をObjectで出力するためのメソッドを定義してあげることで、スーパークラスからサブクラスへのキャストを実現する。

実装例

Class InterfaceClass


'' プロパティ
Public porp as String 
 
'' イミディエイトウィンドウに出力する
Public Sub printOut() As String
End Sub
 
'' 自己をObject型で出力する
Public Function Object() As Object
End Function

Class ImplementClass

 
'' InterfaceClassを実装する
Implements InterfaceClass
 
'' スーパークラスのGet,Letのため、
'' 値を保持しておくためのプロパティ
Private prop As String
 
'' Getter
Public Property Get InterfaceClass_prop() As String
  InterfaceClass_prop = prop
End Property
 
'' Letter
Public Property Let InterfaceClass_prop(RMS As String)
  prop = RMS
End Property
 
'' printOutプロシージャの実装
'' Debug.Print で出力する
Public Sub InterfaceClass_printOut() As String
  Debug.print "Hello, " & prop
End Sub
 
'' Objectプロシージャの実装
'' 単純に、自身をObject型として出力する
Public Function Object() As Object
  Set Object = Me
End Function
 
'' サブクラスとしてのプロシージャ
'' メッセージボックスを表示させる。
'' このメソッドは、サブクラスとして実行することはできる。
'' ただ、スーパークラスからは呼び出すことはできない。
Public Sub outputMessage() As String
  MsgBox "Welcome, " & prop
End Sub

MainModule
 
Public Sub Main()
  Dim ins As InterfaceClass
 
  '' ImplementClassのインスタンスをinsに格納する
  Set ins = New ImplementClass
 
  ins.prop = "Neko"
 
  '' InterfaceClassとしてprintOutを実行
  Call ins.printOut '' Hello, Neko としてイミディエイトウィンドウに出力
  '' outputMessageはスーパークラスとしては呼ぶことができない
  '' ins.outputMessage '' Errorになる
 
  '' ImplementClassとしての変数
  Dim obj As ImplementClass
  '' そのままInterfaceクラスのそれをSetすることはできない
  '' Set obj = ins '' Errorになる
 
  '' ObjectプロシージャでObject型として出力することで、
  '' ダウンキャストが可能
  Set obj = ins.Object
 
  obj.outputmessage  '' MessageBoxで「Welcome, Neko」として出力する
  obj.printOut       '' イミディエイトウィンドウに「Hello, Neko」として出力することもできる
End Sub

コメント

このブログの人気の投稿

リモートワークをLogicoolのマウスとキーボードで複数PC切り替えて優勝した

SUPERHOTがいかにSUPERHOTか語りたい