Ant*_*yer 3 oop excel vba interface implements
我正在阅读这里创建类工厂:https : //rubberduckvba.wordpress.com/2018/04/24/factories-parameterized-object-initialization/我很困惑为什么他们将实现的函数设为私有,不会我们希望它们是公开的,以便我们可以访问它们?
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Something"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Type TSomething
Bar As Long
Ducky As String
End Type
Private this As TSomething
Implements ISomething
Public Function Create(ByVal initialBar As Long, ByVal initialDucky As String) As ISomething
With New Something
.Bar = initialBar
.Ducky = initialDucky
Set Create = .Self
End With
End Function
Public Property Get Self() As ISomething
Set Self = Me
End Property
Public Property Get Bar() As Long
Bar = this.Bar
End Property
Friend Property Let Bar(ByVal value As Long)
this.Bar = value
End Property
Public Property Get Ducky() As String
Ducky = this.Ducky
End Property
Friend Property Let Ducky(ByVal value As String)
this.Ducky = value
End Property
Private Property Get ISomething_Bar() As Long
ISomething_Bar = Bar
End Property
Private Property Get ISomething_Ducky() As String
ISomething_Ducky = Ducky
End Property
Run Code Online (Sandbox Code Playgroud)
另外,为什么需要为接口中的公共变量提供 get 和 let 属性?
他们应该是Private。
原因是因为接口在 VBA 中是如何工作的:Public类模块的成员定义了它的默认接口。这意味着公共成员Class1定义了成员Class2必须实现的内容Implements Class1。
因此,如果您Class1_DoSomething公开,那么您将在 的默认接口上公开该成员Class2,这……一点也不漂亮。
您访问对象的接口取决于您如何声明它。
Dim thing As Class1
Set thing = New Class1
Run Code Online (Sandbox Code Playgroud)
如果thingis或 implements Class1,则此声明之后的代码可以调用默认接口公开的所有成员Class1(即其公共成员)。
如果Class1实现ISomething并且我们像这样声明它:
Dim thing As ISomething
Set thing = New Class1
Run Code Online (Sandbox Code Playgroud)
现在我们要使用的成员是由ISomething类/接口的公共成员定义的成员。
当你实现一个接口或处理事件时,你永远不应该手动输入签名;相反,从代码窗格的左上角下拉列表中选择接口(或事件提供程序),然后从右上角的下拉列表中选择一个成员:VBE 会自动创建具有正确签名的正确过程,并且它始终是一个Private成员-拇指法则,任何有下划线在VBA中的名称有没有业务Public
至于为什么必须为接口类上定义为公共字段(/变量)的内容提供Get和Let访问器......字段是实现细节,它们永远不应该Public放在首位。对象公开属性,而不是字段 - 为实现类的私有内部状态保留字段。
原因是技术性的:VBA 代码被编译成一个 COM 类型库,该库看到您的公共变量并说“这将必须是一个 PUT 和一个 GET 方法”,因此实现该接口的 VBA 代码需要实现每个公共字段的属性,因为公共字段编译为属性。
这对于在类模块上公开公共字段的做法确实具有有趣的含义(无论如何都将封装与编译分解为属性!),但这是另一个讨论。