VBA继承模式

VBA继承模式,vba,Vba,VBA是基于COM的,COM不进行继承。但我想我可能有一个模式,它近似于它的某些方面: Animal.cls Public Sub Speak() Err.Raise 418, , "Not supported" End Sub Dog.cls Implements Animal Private mBase As Animal Private Sub Class_Initialize() Set mBase = New Animal End Sub Priva

VBA是基于COM的,COM不进行继承。但我想我可能有一个模式,它近似于它的某些方面:

Animal.cls

Public Sub Speak() 
    Err.Raise 418, , "Not supported" 
End Sub 
Dog.cls

Implements Animal 

Private mBase As Animal 

Private Sub Class_Initialize() 
  Set mBase = New Animal 
End Sub 

Private Sub Animal_Speak() 
   Me.Speak 
End Sub 

Public Sub Speak() 
   MsgBox "Woof!" 
End Sub 

Public Property Get Base() As Animal 
    Set Base = mBase 
End Property 
Test.bas

Sub Test() 
    Dim animal As animal: Set animal = New dog 
    Dim dog As dog: Set dog = New dog 
    Dim object As Object: Set object = New dog 

    dog.Speak      ' direct      : Woof! 
    animal.Speak   ' polymorphic : Woof! 
    object.Speak   ' late-bound  : Woof! 
    dog.Base.Speak ' fake upcast : Err 418 
End Sub
因此,Dog.cls中实现的接口成员Animal_Speak(它是私有的,以防止直接调用)将调用转发给public Speak方法,public Speak方法可以将其委托给Animal.cls中的等效子对象(“继承”)或替换为其他对象(“覆盖”)

此外,Dog.cls中的Base属性在调用方确实希望基本行为(向上转换)的情况下公开

(引用术语,因为它们只是近似值)

因此,我的问题是:

  • 这是一种已知的模式吗?如果是,它是否普遍存在
  • 有什么缺点吗

  • 您正在实现的模式是一种组合形式,它是继承的常用代理,即使在支持类继承的语言中也是如此。你看,继承有它的缺点,组合往往比它更受欢迎

    组合不需要接口。事实上,每当您在类中封装对象的实例,然后公开内部对象的部分(或全部)成员时,您都在使用组合

    在您的特定示例中,您使用的是一个“抽象类”(
    Animal
    -接口),这没有多大意义,因为接口不需要像下面这样直接实例化:

    在实际代码中,您可以有一个
    IRepository
    接口,一个实现它的
    ProductSqlRepository
    (然后是
    SupplierSqlRepository
    ,然后是
    OrderSqlRepository
    ,等等),您可以使用一些
    SqlRepository
    类来组合实现,这些类公开所有实现使用的通用功能,每个实现都有自己的特定方式:同时,客户端代码只需要知道/关心
    IRepository


    您正在通过接口继承发现VBA中多态性的可能性,这与类继承不同

    通过类继承,您可以使用
    virtual
    甚至
    abstract
    方法来
    重写派生类中的

    使用.NET风格的接口继承,您可以拥有一个扩展另一个接口的接口,实现类型可以只实现该接口以满足编译器的要求—它公开它所扩展的所有接口的成员

    通过VBA风格的接口继承,您可以得到一个可以实现接口的类。一两个。或者三个。或者更多。。。就像COM类型那样

    那就是。。已经相当棒了

    它被称为面向对象编程-OOP有4个功能:

    • 抽象
    • 封装
    • 继承(sad VBA)
    • 多态性
    在很多编程语言中,如Java和C#,这是一种流行的范例。理想的OOP代码是可靠的、松散耦合的代码,可以轻松地进行单元测试。坚实的原则指导了许多OOP设计:

    • [S] 单一责任原则
    • [O] 笔/闭合原理
    • [五十] 伊斯科夫代换原理
    • [一] 界面分离原理
    • [D] 依附反转原理
    尽管缺乏继承功能,VBA仍然可以尊重这些OOP原则,同时也支持其无构造函数的COM特性。关于代码审查,以及实现的后续文章,对其进行了非常强大的演示

    但是,即使不使用接口,在OOP中思考也可以封装任何功能,并以可重用组件的方式编写。这说明了如何从运行演示的UI(用户表单或工作表)代码转移到让UI成为应用程序逻辑中的I/O设备

    通过使用VBA学习OOP,您正在塑造您的思维过程,并开始了从过程范式到面向对象代码奇迹的旅程。一旦掌握了这一点,您将希望将您的经验扩展到成熟的类继承,并发现委托和匿名函数,甚至可能研究函数式编程范式,这是另一种完全不同的代码思考方式,就像OOP是过程式的

    VBA IDE,辉煌的VBE,不幸的是上次更新是在VB6风靡一时的时候,没有太多鼓励OOP的特性。甚至可以说VBE非常讨厌OOP:

    • Project Explorer唯一的文件夹是模块类型,因此包含许多类的项目很快就会成为导航噩梦
    • 没有“转到实现”功能可以轻松定位接口的实现
    • 没有重构工具
    • 没有单元测试
    • 没有静态代码分析
    公平地说,单元测试和重构工具在1999年并不像今天那样普及(AFAIK)。不过,VBA中OOP的缺点是IDE本身缺乏特性

    幸运的是,VBIDE有一个可扩展性模型并支持外接程序。因此,您可以获得并拥有所有这些功能,并在VBA中编写OOP代码,而无需不断地对IDE功能的缺乏感到愤怒

    免责声明:我管理Rubberduck开源项目,该项目托管于

    Set mBase = New Animal