VBA继承,超级模拟

时间:2010-09-08 15:22:45

标签: vba excel-vba inheritance excel

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

--- A级----

implements B
public sub B_do()
end sub

- B级----

public sub do()
end sub

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

补充:同样的问题http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/5a83d794-3da1-466a-83d3-5d2eb0a054b2

补充说:不可能跨类别分享变量。你应该实现属性(与函数相同)。

3 个答案:

答案 0 :(得分:21)

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

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

http://msdn.microsoft.com/en-us/library/aa716285(VS.60).aspx

有一章关于“代码重用的许多(国际)面”描述了这个惯例:

http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx

MS描述它的方式是:

  

除了实现抽象   接口,您可以重用您的代码   实现一个接口   普通班,然后有选择地   委托给隐藏的实例   类。

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

编辑不符合评论:

要回答你在评论中提出的问题,好吧,A a B.当你制作A工具B的界面时,你基本上就是说你可以将A的实例看作是它实际上是B类型。在VBA中,你这样做的方法是声明一个B类型的变量,然后将它设置为A的实例。当你像B一样调用它时,VBA会知道该怎么做:

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,所以我不知道。

答案 1 :(得分:1)

一个人可以拉一个模仿继承的把戏。通过使用默认成员属性可以工作。

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

blog post提供了完整的详细信息,但此处的作者(披露,我)使用“基本”而不是“超级”

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

我还指出,这并不像C#那样公开所有基类的内部胆量。这意味着我的方法不会遇到脆弱的基类问题。即我的方法保留了封装,使它更好的恕我直言。

答案 2 :(得分:1)

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

'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()

enter image description here