vba VBA继承,super的模拟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3669270/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
VBA inheritance, analog of super
提问by nikaan
For example I have class A which implements class B
例如,我有实现类 B 的 A 类
---class A----
---A类----
implements B
public sub B_do()
end sub
--class B----
——B级——
public sub do()
end sub
How can I call do() from A? (super.do()) So, how I can define some common variable for both classes? Now I can inherit only functions, sub and properties...
如何从 A 调用 do()?(super.do()) 那么,我如何为两个类定义一些公共变量?现在我只能继承函数、子函数和属性...
added: same question http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/5a83d794-3da1-466a-83d3-5d2eb0a054b2
补充:同样的问题http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/5a83d794-3da1-466a-83d3-5d2eb0a054b2
added: It is not possible to share variable across hierarhy of classes. You should implements property (same way as functions).
补充:不可能跨类的层次结构共享变量。您应该实现属性(与函数相同的方式)。
回答by jtolle
The usual way to do this in VBA is to have A contain an instance of B as well as having A implement B's interface, and then delegate calls to the B interface of A to the internal B.
在 VBA 中执行此操作的通常方法是让 A 包含 B 的实例以及让 A 实现 B 的接口,然后将对 A 的 B 接口的调用委托给内部 B。
This is old stuff, but see the Visual Studio 6.0 Programmer's Guide:
这是旧东西,但请参阅 Visual Studio 6.0 程序员指南:
http://msdn.microsoft.com/en-us/library/aa716285(VS.60).aspx
http://msdn.microsoft.com/en-us/library/aa716285(VS.60).aspx
There is a chapter on "The Many (Inter)Faces of Code Reuse" that describes this convention:
有一章描述了这个约定:
http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx
http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx
The way MS describes it is:
MS描述它的方式是:
In addition to implementing abstract interfaces, you can reuse your code by implementing the interface of an ordinary class, and then selectively delegating to a hidden instance of the class.
除了实现抽象接口之外,您还可以通过实现一个普通类的接口来重用您的代码,然后有选择地委托给该类的一个隐藏实例。
This means that implementation inheritance requires lots of explicit delegation methods. There's even a chapter subheading: "Doesn't This Get Tedious?". Yet another reason why OOP in VBA is a PITA (TM)...
这意味着实现继承需要大量的显式委托方法。甚至有一章小标题:“这不是很乏味吗?”。VBA 中的 OOP 的另一个原因是 PITA (TM)...
EDIT THAT WON'T FIT IN A COMMENT:
不适合评论的编辑:
To answer the question you posed in your comment, well, an A isa B. When you make A implement B's interface, you are essentially saying that you can treat an instance of A as if it is actually of type B. In VBA, the way you do that is by declaring a variable of type B, and then setting it to an instance of A. VBA will know what to do when you call it like a B:
为了回答您在评论中提出的问题,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
As far as what you see in the debug window, I don't why it appears that way. And as far as forced delegation, I'm not sure what you mean. VBA automatically dispatches calls to the B interface to the right methods in the A class. If you mean automatically generating the code to inherit B's implementation in the manner described above, there's nothing like that I know of for VBA. I think the various "professional" versions of VB6 could do that, but I've never used VB6 so I don't know.
至于您在调试窗口中看到的内容,我不明白为什么会这样。至于强制授权,我不确定你的意思。VBA 自动将对 B 接口的调用分派到 A 类中的正确方法。如果您的意思是自动生成代码以按照上述方式继承 B 的实现,那么我所知道的 VBA 没有任何类似的东西。我认为 VB6 的各种“专业”版本都可以做到这一点,但我从未使用过 VB6,所以我不知道。
回答by Lucius Matos
This is the way I have used it a long time to simulate an abstract class through the interface.
这是我用了很久的方式,通过接口模拟一个抽象类。
'class module: IBase
'We define a base interface
'
Sub go(): End Sub
Sub gogo(): End Sub
Now let's define the other classes, beginning with the abstract class 'B'.
现在让我们定义其他类,从抽象类“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
Let's create class 'A' which implements the abstract class 'B'
让我们创建实现抽象类“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
And finally, let's create the 'main' module.
最后,让我们创建“主”模块。
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
And the output, in the verification window, will be:
验证窗口中的输出将是:
A: Local method 1
A: go()
B: super.go()
B: super.gogo()
回答by S Meaden
One can pull a trick to mimic inheritance. It works by using the default member property.
人们可以使用一种技巧来模仿继承。它通过使用默认成员属性来工作。
If you give your derived class a property called Super whose type is the superclass then make that the default member (by exporting and editing file to include Attribute Item.VB_UserMemId = 0, re-importing) then you can reach the superclass by just a pair of round brackets (which resolves to the default member).
如果你给你的派生类一个名为 Super 的属性,它的类型是超类然后使它成为默认成员(通过导出和编辑文件以包含Attribute Item.VB_UserMemId = 0,重新导入)那么你可以通过一对圆括号(它解析到默认成员)。
This blog postgives the full details but author (disclosure, me) there uses 'Base' instead of 'Super'
这篇博文提供了完整的细节,但作者(披露,我)在那里使用“Base”而不是“Super”
Hopefully that syntax is tight enough for you.
希望该语法对您来说足够紧凑。
I also point out that this does not expose all the base class's internal guts like C# does. This means my method does not suffer from the fragile base class problem. I.e. my method retains encapsulation making it better IMHO.
我还指出,这不会像 C# 那样暴露所有基类的内部结构。这意味着我的方法不会受到脆弱基类问题的影响。即我的方法保留封装使其更好恕我直言。


