Tox*_*iro 8 oop vba properties interface class
有什么区别
Public Variable As Integer
Run Code Online (Sandbox Code Playgroud)
和
Private pVariable As Integer
Public Property Let Variable(ByVal lVariable As Integer)
pVariable = lVariable
End Property
Public Property Get Variable()
Variable = pVariable
End Property
Run Code Online (Sandbox Code Playgroud)
在VBA类模块中?
为什么我会使用第二个版本?
小智 21
尽管VBA是面向对象的,但它在很多方面仍然受到限制,但就这个例子而言,它应该足以理解VBA中OOP的基础知识.
你的代码
Private pVariable As Integer
Public Property Let Variable(ByVal lVariable As Integer)
pVariable = lVariable
End Property
Public Property Get Variable()
Variable = pVariable
End Property
Run Code Online (Sandbox Code Playgroud)
是错的有点不必要.
注意:您可以在需要处理错误/验证数据的情况下执行此操作,但通常如果设置和获取您不会这样做的值那么简单.
如果您同时公开Let/Set和Get属性,为什么还需要私有支持字段?您需要的只是公共变量本身,不需要属性.
当你只需暴露其中一个属性而不是另一个属性(即只有setter或getter)时,故事会改变360度.通过一个例子可能更容易理解......
例
让我们从一个简单的"银行"示例开始(显然你不会在现实生活中的VBA中这样做,但它是一个很好的概念来评估作为基础)
想象一下,你必须建立一个类来模拟银行账户.你需要一个方法deposit和withdraw帐户的钱以及显示balance.
通常情况下,您不会有setter该balance字段,因为应该允许任何人明确set表示余额.(如果你知道允许这样做的银行,请告诉我;)).实际余额应该是私人变量.应该有一个暴露它的财产,这就是你应该考虑的一切.
考虑一个VBA类(一个接口)
IAccountServices.cls
Sub Deposit(amount As Double)
End Sub
Sub WithDraw(amount As Double)
End Sub
Run Code Online (Sandbox Code Playgroud)
和另一个代表帐户的类
Account.cls
Implements IAccountServices
' balance should be private
' cause you should only have a getter for it
' you should only be able to set the balance inside this class
' based on the operations
Private accBalance As Double
' see Getter only - no setter
Public Property Get Balance() As Double
Balance = accBalance
End Property
Public Function Deposit(amount As Double)
accBalance = accBalance + amount
End Function
Public Function WithDraw(amount As Double)
accBalance = accBalance - amount
End Function
Private Sub IAccountServices_Deposit(amount As Double)
accBalance = accBalance + amount
End Sub
Private Sub IAccountServices_WithDraw(amount As Double)
accBalance = accBalance - amount
End Sub
Run Code Online (Sandbox Code Playgroud)
注意:这显然是最简单的简单示例,它没有任何错误处理或检查余额是否足以撤销等.这仅用于演示目的,不用于实际应用程序.
通过这种封装,我立即看到/知道
accBalance是一个私人领域,无法在课外任何地方访问.
我只能检索balance()并且没有在Account类的实例上显式设置它.
我可以deposit()和withdraw()钱从账户(可公开访问的方法)
在您的标准模块(module1)中,即使具有智能感,您也会列出.Balance,并且您的所有库/类用户都需要担心.
现在有一个标准的编码模块来测试这两个类(Module1)
Sub Main()
Dim myAccount As Account
Set myAccount = New Account
Debug.Print "Starting Balance: " & myAccount.Balance
myAccount.Deposit (2000)
Debug.Print "Deposited: 2000"
myAccount.WithDraw (250)
Debug.Print "Withdrew: 250"
Debug.Print "Ending Balance: " & myAccount.Balance
' can't set balance
' myAccount.Balance = 999999999999999999999999
End Sub
Run Code Online (Sandbox Code Playgroud)
要获得VBA OOP的介绍我可以推荐:
属性允许外部访问,就好像属性是公共字段一样,同时允许类保持对数据的控制.
Get属性可以计算实际上不存在于类中的"变量".例如,质量Get属性可能会返回密度乘以体积的乘积.
Private density as Double
Private volume as Double
Private potentialEnergy
Public Property Get mass() As Double
mass = density*volume
End Property 'Property Get mass
Run Code Online (Sandbox Code Playgroud)
一个让财产可能会检查的有效性,如不接受负积.或者它可以保持对象的字段属性同步:
Public Property Let density(rho as Double)
if rho > 0 then
density = rho
potentialEnergy = density * volume * gravity * height
End Property 'Property Get mass
Run Code Online (Sandbox Code Playgroud)
您还可以通过省略Let或Get属性将属性设置为只读(或只写 - 不要使用太多).
除了性能略有下降之外,最好从一开始就为允许公共访问的任何字段使用属性,即使属性最初是微不足道的,以便于将来修改类.