web-dev-qa-db-ja.com

VBAはOOP言語であり、多態性をサポートしていますか?

私は実際に最初の[〜#〜] vba [〜#〜]プロジェクトに取り組んでいます。 (C++から来る)

クラスとポリモーフィズムを実装することにより、既存の[〜#〜] vba [〜#〜]Microsoft Excelワークブックで使用されるプロジェクトを改善したいと思います。

私の問題は:

1-[〜#〜] vba [〜#〜]はオブジェクト指向プログラミングではないことを説明する多くの記事/フォーラムを読みました( [〜#〜] oop [〜#〜])言語であり、多態性をサポートしていません。

それらのいくつかは、キーワードImplementsを使用して回避策を提案します。

2-また、 this one のようなWebページを見つけました。これは、OOPおよびキーワードを使用したVBAのポリモーフィズムの実行方法を説明しますlikeInheritsOverridesOverridable MustOverrides

だから私の質問は:

[〜#〜] vba [〜#〜][〜#〜] oop [〜#〜]言語であり、ポリモーフィズムをサポートしていますか?

35
Axel Borja

OOPは4つの「柱」に座っています。

  • check Abstraction-class modulesでオブジェクトを定義することにより、ロジックと概念を簡単に抽象化できます。厳密に言えば、abstractionは、意味のある識別子を使用し、手続きコードをメソッド(クラスメンバー)に抽出することでも実現されます。

    abstractionを示すVBAで記述されたプロシージャの例を次に示します。

    _Public Sub Test(ByVal checkin As Date, ByVal checkout As Date, ByVal custType As CustomerType)
        Dim Finder As New HotelFinder
        InitializeHotels Finder
        Debug.Print Finder.FindCheapestHotel(checkin, checkout, custType)
    End Sub
    _

    abstraction levelは非常に高いため、このTestプロシージャが何をしているのかが一目でわかります:implementation detailsabstractedで、より特殊なオブジェクトとメソッドになります。

  • check カプセル化-クラスはプロパティによって公開されるプライベートフィールドを持つことができます。クラスをPublicNotCreatableにして、型を他のVBAプロジェクトに効果的に公開します-クラスモジュールをエクスポートし、お気に入りのテキストエディターで開き、クラス属性を手動で編集し、モジュールを再インポートすることで、実際の読み取り専用タイプを実現できます。パラメーター化されたコンストラクターがないという事実は無関係です-好きなパラメーターをすべて取得してインスタンスを返すファクトリーメソッドを記述するだけです。これはCOMであり、COMはとにかく工場が好きです。

    上記のスニペットencapsulatesHotelFinderオブジェクトのCollectionクラスがSetオブジェクトを介して、_Property Get_アクセサーを介してのみ公開する方法の例を次に示します。この参照、encapsulated

    _Private Type TFinder
        Hotels As Collection
    End Type
    Private this As TFinder
    
    Public Property Get Hotels() As Collection
        Set Hotels = this.Hotels
    End Property
    
    Private Sub Class_Initialize()
        Set this.Hotels = New Collection
    End Sub
    
    Private Sub Class_Terminate()
        Set this.Hotels = Nothing
    End Sub
    _
  • check Polymorphism-Implementsを使用すると、抽象インターフェース(および具象クラスも)を実装できます。その後、同様にできるISomething抽象化に対してコードを記述できますFooまたはBar(与えられたFooBarは両方ともISomethingを実装します)-これまでに必要なコードはすべてISomethingです。メソッドのオーバーロードはVBAにはない言語機能ですが、オーバーロードはポリモーフィズムとは関係がありません。これは基本となる異なるフォーム(データ型)に対して同じインターフェイスを提示する機能

    ここに適用されたポリモーフィズムの例があります-_LogManager.Register_メソッドは、ILoggerインターフェイスを実装する任意のオブジェクトで動作します;ここでDebugLoggerFileLogger-そのインターフェイスの大きく異なる2つの実装が登録されています。後でLogManager.Log(ErrorLevel, Err.Description)が呼び出されると、2つの実装はそれぞれ独自の処理を行います。 DebugLoggerimmediateツールウィンドウに出力し、FileLoggerは指定されたログファイルにエントリを書き込みます。

    _LogManager.Register DebugLogger.Create("MyLogger", DebugLevel)
    LogManager.Register Filelogger.Create("TestLogger", ErrorLevel, "C:\Dev\VBA\log.txt")
    _
  • nope Inheritance-VBAでは、別の型から派生させることはできません。継承はサポートされていません。


問題は、継承をサポートしていない言語を「オブジェクト指向」として修飾できるかどうかです。composition は、多くの注意事項がある継承よりも望ましい場合が非常に多くあります。また、VBAを使用すると、composeオブジェクトを思いのままに作成できます。

VBAはOOP言語ですか?

欠けているものはすべて継承であり、その構成は継承よりも望ましいことを考えると、「はい」と答えたいと思います。以前に本格的なOOP VBAコード(作業単位とリポジトリを備えたModel-View-Presenter、誰か?)を書いたことがあります。これは、「実際のOOP "継承をサポートする言語。

以下にいくつかの例を示します。すべて100%VBAです。

この最後のリンクのコードは最終的にC#に移植され、すぐに VBA IDEのCOMアドイン に進化しました。これにより、リファクタリング、ナビゲーションの改善、コード検査、その他のツールが提供されます。

VBAは、あなたが作る限り制限されます。

82
Mathieu Guindon

短い答えはノーとノーです。

VBAはオブジェクトベースであるため、クラスを定義してオブジェクトのインスタンスを作成できますが、通常、完全なOOP言語に関連付けられる機能はありません。たとえば:

  • カプセル化と抽象化:VBAはこれをある程度提供します。クラスは、パブリックインターフェイスを定義してプライベートに保つことができますが、クラス内のコンストラクターは提供されません。クラスには Class_Inititalize 何らかの構築はできますが、引数を取ることができないイベント。引数を渡すにはpublic factory function が必要になりますが、コンストラクタースタイルのデザインパターンを作成するには回避策が必要です。
  • 継承:VBAには実際には存在しませんが、 ほぼ複製
  • ポリモーフィズム:(Implementsを使用して)インターフェイスを介してある程度達成できますが、関数をオーバーロードする機能は存在せず、各「オーバーロード」には技術的に一意の関数名が必要です。この問題を回避するには、オブジェクトを関数またはサブルーチンへの唯一のパラメーターとして渡し、プロパティの値に応じて手順を変更します。

したがって、オブジェクトをある程度操作でき、MS Officeアプリケーションはオブジェクトモデルに基づいていますが、VBAはオブジェクト指向言語ではありません。多態性は、C++で熟知している範囲では実現できません。

5
stucharo