VBA是OOP语言,它是否支持多态?

时间:2015-08-06 14:13:56

标签: excel vba oop polymorphism

我实际上正在处理我的第一个 VBA 项目。 (来自 C ++

我想通过实现类和多态来改进 Microsoft Excel 工作簿使用的现有 VBA 项目。

我的问题是:

1 - 我读了很多文章/论坛,解释 VBA 不是面向对象的编程( OOP )语言不支持多态性。

其中一些人建议使用关键字实施

进行解决方法

2 - 我还发现了一些像this one这样的网页,这些网页解释了如何使用继承重写等关键字在VBA中执行OOP和多态性/ strong>,可覆盖 MustOverrides

所以我的问题是:

VBA OOP 语言,是否支持多态?

2 个答案:

答案 0 :(得分:78)

OOP坐在4“支柱”上:

  • check 抽象 - 通过在类模块中定义对象,可以轻松完成抽象逻辑和概念。严格地说,抽象也可以通过使用有意义的标识符并将过程代码提取到方法(类成员)中来实现。

    以下是用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
    

    很容易告诉这个Test过程一目了然,因为抽象级别非常高:实现细节抽象的远离更专业的对象和方法。

  • check 封装 - 类可以拥有属性公开的私有字段;可以创建类PublicNotCreatable,有效地将类型暴露给其他VBA项目 - 并且需要一点点努力(通过导出类模块,在您喜欢的文本编辑器中打开它,手动编辑类属性,以及重新导入模块),你可以实现实际的只读类型。没有参数化构造函数的事实是无关紧要的 - 只需编写一个工厂方法,它接受您喜欢的所有参数并返回一个实例。这是COM,COM无论如何都喜欢工厂。

    以下是上述代码段中的HotelFinder类如何封装 Collection对象并仅通过Property Get访问者公开它的示例 - 此外的代码class简直不能Set这个引用,它是封装的

    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 多态性 - Implements允许您实现抽象接口(以及具体类),然后您可以针对{{1}编写代码抽象也可以是ISomethingFoo(给定BarFoo都实现Bar) - 以及所有需要的代码见ISomething。方法重载是VBA缺少的语言特性,但重载与多态无关,即 the ability to present the same interface for differing underlying forms (data types)

    以下是应用多态的示例 - ISomething方法很乐意使用任何实现LogManager.Register接口的对象;这里有一个ILogger和一个DebugLogger - 两个完全不同的接口实现,正在注册;当稍后调用FileLogger时,这两个实现将各自执行自己的操作; LogManager.Log(ErrorLevel, Err.Description)将输出到 immediate 工具窗口,DebugLogger会将一个条目写入指定的日志文件中:

    FileLogger
  • nope 继承 - VBA不允许您从另一个类型派生类型:不支持继承。

现在问题是,可以将不支持继承的语言限定为“面向对象”吗?事实证明组合通常比继承更可取,有一些警告。而且VBA会让你对象组合成你心中的内容。

  

VBA是OOP语言吗?

鉴于所有缺少的是继承,并且该组合比继承更好,我很想回答“是”。我之前编写过完整的OOP VBA代码(模型 - 视图 - 演示者,工作单元和存储库,任何人?),我不会用支持继承的“真正的OOP”语言编写任何不同的代码。

以下是几个例子,全部是100%VBA:

最后一个链接中的代码最终被移植到C#,并迅速演变为a COM add-in for the VBA IDE,为您提供重构,更好的导航,代码检查和其他工具。

VBA只是你做的限制。

答案 1 :(得分:4)

简短的答案是否定的。

VBA是基于对象的,允许您定义类并创建对象的实例,但它缺少通常与完全成熟的OOP语言相关联的功能,例如:

  • 封装和抽象:VBA在一定程度上提供了这一点。可以使用定义的公共接口保持类的私有,但是类中没有构造函数的规定。类具有Class_Inititalize事件,可以执行某些构造但不能接受参数。传递参数需要公共factory function解决方法仍然需要创建构造函数样式的设计模式。
  • 继承:VBA中确实不存在,但可以是almost replicated
  • 多态性:可以通过接口(使用Implements)在一定程度上实现,尽管不存在重载函数(例如)的能力,并且每个“重载”在技术上都需要唯一的函数名称。您可以通过将对象作为函数或子的唯一参数传入并根据属性的值更改过程来解决此问题。

因此,虽然您可以在一定程度上使用对象,而MS Office应用程序基于对象模型,但VBA并不是一种面向对象的语言。在C ++中你不熟悉多态性。