VBA继承,模拟超级

VBA继承,模拟超级,vba,excel,inheritance,Vba,Excel,Inheritance,例如,我有一个实现类B的类A ---甲级---- --B类---- 如何从一个函数调用do()?(super.do())那么,我如何为这两个类定义一些公共变量呢?现在我只能继承函数、子函数和属性 补充:同样的问题 补充:不可能在类的层次结构中共享变量。您应该实现属性(与函数的方式相同)。在VBA中执行此操作的通常方法是让A包含B的实例以及实现B的接口,然后将对A的B接口的调用委托给内部B 这是老东西,但请参阅Visual Studio 6.0程序员指南: 有一章是关于“代码重用的许多(相互)面

例如,我有一个实现类B的类A

---甲级----

--B类----

如何从一个函数调用do()?(super.do())那么,我如何为这两个类定义一些公共变量呢?现在我只能继承函数、子函数和属性

补充:同样的问题


补充:不可能在类的层次结构中共享变量。您应该实现属性(与函数的方式相同)。

在VBA中执行此操作的通常方法是让A包含B的实例以及实现B的接口,然后将对A的B接口的调用委托给内部B

这是老东西,但请参阅Visual Studio 6.0程序员指南:

有一章是关于“代码重用的许多(相互)面”的,描述了此约定:

MS对此的描述是:

除了实现抽象 接口,您可以通过 实现 普通类,然后有选择地 委派给的隐藏实例 班级

这意味着实现继承需要大量显式的委托方法。甚至还有一个章节副标题:“这不是很乏味吗?”。VBA中OOP是PITA(TM)的另一个原因

编辑不适合评论的内容:

为了回答您在评论中提出的问题,A就是B。当您创建一个实现B的接口时,您本质上是说您可以将A的实例视为实际上是B类型的。在VBA中,您这样做的方式是声明一个B类型的变量,然后将其设置为A的实例。VBA将知道当您像A B一样调用它时该怎么做:

Dim usedAsB as B
Dim anA as A

Set anA = New A
Set usedAsB = anA    'fine since A implements B

usedAsB.something()    'will call B_something() defined in class A

就您在调试窗口中看到的情况而言,我不知道为什么会出现这种情况。至于强制授权,我不知道你的意思。VBA自动将对B接口的调用分派给A类中正确的方法。如果您的意思是以上述方式自动生成代码以继承B的实现,那么我所知道的VBA中就没有这样的代码了。我认为各种“专业”版本的VB6都可以做到这一点,但我从来没有使用过VB6,所以我不知道。

人们可以用一些技巧来模仿继承。它通过使用默认成员属性工作

如果为派生类指定一个名为Super的属性,其类型为超类,然后将该属性设置为默认成员(通过导出和编辑文件以包含
Attribute Item.VB_UserMemId=0
,重新导入),则只需一对圆括号(解析为默认成员)即可访问超类

这提供了完整的细节,但作者(披露,我)在那里使用“Base”而不是“Super”

希望语法对您来说足够紧凑


我还指出,这并不像C#那样暴露所有基类的内部胆量。这意味着我的方法不存在脆弱的基类问题。也就是说,我的方法保留了封装,这使它在IMHO中变得更好。

这是我很长时间以来通过接口模拟抽象类的方式

'class module: IBase
'We define a base interface
'
Sub go(): End Sub

Sub gogo(): End Sub
现在让我们定义其他类,从抽象类“B”开始

'
'class module: B
'
Implements IBase

'Daughter classes should implement 'go'
'Note that the method is 'Public'
Public Sub go(): End Sub

'Let's agree that every daughter class implements the method
'abstract 'super' that returns the IBase interface
Public Property Get super() As IBase: End Property

'
'The signature of other abstract methods can be stated here
'
'Public Sub goGoChild(): End Sub
'Public Function goGoGoChild2(): End Function
'

'
'Note that the methods are accessible through the IBase interface
'
Private Sub IBase_go()
    Debug.Print "B: super.go()"
End Sub

Private Sub IBase_gogo()
    Debug.Print "B: super.gogo()"
End Sub
让我们创建实现抽象类“B”的类“A”

'
'class module: 'A'
'

'We started implementing the abstract class B
Implements B

'we define a private type 'myType'
Private Type myType

    'variable that references an instance of 'B'
    objB As B

    'variable that references the interface of 'B'
    objIB As IBase

End Type

'VBA version of 'this'
Private this As myType

'
'Every class that implements 'B' (abstract class)
'you must initialize in your constructor some variables
'of instance.
'
Private Sub Class_Initialize()

    With this

        'we create an instance of object B
        Set .objB = New B

        'the variable 'objIB' refers to the IBase interface, implemented by class B
        Set .objIB = .objB

    End With

End Sub


'Visible only for those who reference interface B
Private Property Get B_super() As IBase

    'returns the methods implemented by 'B', through the interface IBase
    Set B_super = this.objIB

End Property

Private Sub B_go()
    Debug.Print "A: go()"
End Sub
'==================================================

'Class 'A' local method
Sub localMethod1()
    Debug.Print "A: Local method 1"
End Sub
最后,让我们创建“主”模块

Sub testA()

    'reference to class 'A'
    Dim objA As A

    'reference to interface 'B'
    Dim objIA As B

    'we create an instance of 'A'
    Set objA = New A

    'we access the local methods of instance 'A'
    objA.localMethod1

    'we obtain the reference to interface B (abstract class) implemented by 'A'
    Set objIA = objA

    'we access the 'go' method, implemented by interface 'B'
    objIA.go

    'we go to the 'go' method of the super class
    objIA.super.go

    'we access the 'gogo' method of the super class
    objIA.super.gogo

End Sub
在验证窗口中,输出为:

A: Local method 1
A: go()
B: super.go()
B: super.gogo()

谢谢!你知道VBA中类的精确实例的一些来源吗?在调试中,我看到类A有一个类型为B的字段。因此,在internet的某个地方,我发现类型A的对象实际上是类型B(!)的对象;通过强制授权,我将通读《程序员指南》中关于“使用对象编程”的其他章节。至于另一个问题,我将编辑我的答案,因为它可能不适合评论。所以,几分钟后看一下……这绝对是非常好的,而且比其他答案更清楚。
Sub testA()

    'reference to class 'A'
    Dim objA As A

    'reference to interface 'B'
    Dim objIA As B

    'we create an instance of 'A'
    Set objA = New A

    'we access the local methods of instance 'A'
    objA.localMethod1

    'we obtain the reference to interface B (abstract class) implemented by 'A'
    Set objIA = objA

    'we access the 'go' method, implemented by interface 'B'
    objIA.go

    'we go to the 'go' method of the super class
    objIA.super.go

    'we access the 'gogo' method of the super class
    objIA.super.gogo

End Sub
A: Local method 1
A: go()
B: super.go()
B: super.gogo()