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

问题描述 投票:33回答:2

我实际上是在开发我的第一个VBA项目。 (来自C ++)

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

我的问题是:

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

其中一些人使用关键字Implements提出了一种解决方法。

2 - 我还发现了一些像this one这样的网页,它们解释了如何使用Inherits,Overrides,Overridable,MustOverrides等关键字在VBA中执行OOP和多态。

所以我的问题是:

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

excel vba oop polymorphism
2个回答
82
投票

OOP坐在4个“支柱”上:

  • 抽象 - 通过在类模块中定义对象,可以轻松地完成抽象逻辑和概念。严格地说,通过使用有意义的标识符并将过程代码提取到方法(类成员)中也可以实现抽象。 这是一个用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程序一目了然,因为抽象级别非常高:实现细节被抽象成更专业的对象和方法。
  • 封装 - 类可以具有属性公开的私有字段;类可以制作PublicNotCreatable,有效地将类型暴露给其他VBA项目 - 并且通过一些努力(通过导出类模块,在您喜欢的文本编辑器中打开它,手动编辑类属性,并重新导入模块),可以实现实际的只读类型。没有参数化构造函数的事实是无关紧要的 - 只需编写一个工厂方法,它接受您喜欢的所有参数并返回一个实例。这是COM,COM无论如何都喜欢工厂。 下面是一个例子,说明上面代码片段中的HotelFinder类如何封装一个Collection对象并且只通过Property Get访问器公开它 - 这个类之外的代码根本不能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
  • 多态性 - Implements允许你实现抽象接口(以及具体类),然后你可以编写针对ISomething抽象的代码,它也可以是FooBar(给定FooBar都实现ISomething) - 以及所有代码需要看到的是ISomething。方法重载是VBA缺乏的语言特性,但重载与多态无关,即the ability to present the same interface for differing underlying forms (data types)。 这是应用多态的一个例子 - LogManager.Register方法很乐意使用任何实现ILogger接口的对象;这里有一个DebugLogger和一个FileLogger - 两个截然不同的接口实现,正在注册;当稍后调用LogManager.Log(ErrorLevel, Err.Description)时,这两个实现将各自执行自己的操作; DebugLogger将输出到即时工具窗口,FileLogger将在指定的日志文件中写入一个条目: LogManager.Register DebugLogger.Create("MyLogger", DebugLevel) LogManager.Register Filelogger.Create("TestLogger", ErrorLevel, "C:\Dev\VBA\log.txt")
  • 继承 - VBA不允许您从另一个派生类型:不支持继承。

现在的问题是,一种不支持继承的语言是否可以被称为“面向对象”?事实证明,组合通常比继承更受欢迎,这有一些警告。 VBA会让你根据自己的内心构建对象。

VBA是OOP语言吗?

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

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

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

VBA只是限制你做它。


5
投票

简短的答案是否定的。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.