jto*_*lle 5 oop vba encapsulation private-members
我做了大量的Excel VBA编程,但不是很多面向对象的.这是偶然出现的东西,这让我感到困扰,我想知道是否有一些我缺少的东西.
在VBA中,假设我有一个C类定义了一些私有成员,如下所示:
'...
Private hidden1_ As Double
Private hidden2_ As Double
'...
Run Code Online (Sandbox Code Playgroud)
如果VBA像C++或(大多数?)支持OOP的其他语言一样工作,我可以编写一个成员函数来在C类实例之间进行相等测试,如下所示:
'Error: won't compile!
Public Function equal(cinst As C) As Boolean
equal = (hidden1_ = cinst.hidden1_ And hidden2_ = cinst.hidden2_)
End Function
Run Code Online (Sandbox Code Playgroud)
当然,这不会在VBA中编译,因为类成员函数只能访问它们被调用的同一实例的私有类成员.我做过这种事情的最好的方法是改为定义两个成员函数,如下所示:
Public Function equalDef(hidden1 As Double, hidden2 As Double) As Boolean
equalDef = (hidden1_ = hidden1 And hidden2_ = hidden2)
End Function
Public Function equal(cinst As C) As Boolean
equal = cinst.equalDef(hidden1_, hidden2_)
End Function
Run Code Online (Sandbox Code Playgroud)
它很麻烦,它暴露了私有类成员存在的知识,但至少它避免实际暴露私有类成员的价值.
这是我能做的最好的吗?
编辑:
像往常一样,在回答之后,我意识到了一个更好的方式来表达这个问题.它的标题是"有没有更简洁的方法为私人成员的VBA类写一个平等测试?" 当迪克回答时.
再次研究这个问题后,我有了答案,但并不完全令人满意。与 VBA 中的大多数 OOP 一样,它涉及使用适当的接口,但每个类(以及每个接口)都必须位于单独的类模块中,这一事实使其成为一种相当笨拙的执行方式。所以这里是:
假设我有一个名为 MyClass 的类(上面我将其称为“C”,但现在我将其称为“MyClass”以使这一点更清楚。)
要做的事情是定义一个我将在代码中实际使用的接口,该接口仅公开我想要真正公开的有关 MyClass 的内容。假设此代码位于名为 IMyClass 的类模块中:
Public Function calcSomething()
End Function
Public Function equal(cinst As IMyClass) As Boolean
End Function
Run Code Online (Sandbox Code Playgroud)
然后我有一个名为 MyClass 的类,在类模块中使用以下代码定义:
Implements IMyClass
Private hidden1_ As Double
Private hidden2_ As Double
Public Sub init(h1 As Double, h2 As Double)
hidden1_ = h1
hidden2_ = h2
End Sub
Public Function equalDef(hidden1 As Double, hidden2 As Double) As Boolean
equalDef = (hidden1_ = hidden1 And hidden2_ = hidden2)
End Function
Private Function IMyClass_calcSomething() As Variant
IMyClass_calcSomething = hidden1_ * hidden2_
End Function
Private Function IMyClass_equal(cinst As IMyClass) As Boolean
If TypeOf cinst Is MyClass Then
Dim asMyClass As MyClass
Set asMyClass = cinst
IMyClass_equal = asMyClass.equalDef(hidden1_, hidden2_)
End If
End Function
Run Code Online (Sandbox Code Playgroud)
以下是常规模块中的一些代码:
Public Function mkMyClass(h1 As Double, h2 As Double) As IMyClass
Dim ret As MyClass
Set ret = New MyClass
Call ret.init(h1, h2)
Set mkMyClass = ret
End Function
Public Sub useMyClass()
Dim mc1 As IMyClass
Set mc1 = mkMyClass(42, 99)
Dim mc2 As IMyClass
Set mc2 = mkMyClass(42, 99)
Dim mc3 As IMyClass
Set mc3 = mkMyClass(99, 42)
Debug.Print mc1.calcSomething
Debug.Print mc1.equal(mc2)
Debug.Print mc3.calcSomething
Debug.Print mc3.equal(mc2)
End Sub
Run Code Online (Sandbox Code Playgroud)
在“useMyClass”例程中,您可以验证各个 mc1、mc2 和 mc3 变量看不到 MyClass 的“init”或“equalDef”方法。他们只能看到属于接口一部分的“calcSomething”和“equal”方法。
所以,我想,这个问题是正式提出的,但答案并不令人满意。至少它让我有机会重复“VBA 中的 OOP 是 PITA (TM)”...
以下是一些相关的 stackoverflow 答案:
| 归档时间: |
|
| 查看次数: |
1036 次 |
| 最近记录: |