VBA 类模块系列之七——重新设计类的属性

为了阻止类的外部使用者(比如模块1中的代码)随意来修改Person类的性别(Gender)属性,我们要学会使用 … 继续阅读“VBA 类模块系列之七——重新设计类的属性”

为了阻止类的外部使用者(比如模块1中的代码)随意来修改Person类的性别(Gender)属性,我们要学会使用另外一种定义类的属性(Property)的办法。

首先,我们将Public Gender As String 改为Private mstrGender As String,这样性别属性就被保护起来,外部使用者无法直接访问了。(你可能会问:“mstr”是什么?这其实就是程序员在定义变量的时候,约定的一个习俗。“m” 代表模块级(Module)变量,“str”是“String”的缩写。这样,当mstrGender这个变量出现在代码的其他地方时,我们一看前缀“mstr”就知道这是一个模块级的字符型变量。前几篇为了简化,没有变量命名规则的考虑,从本篇开始,我们会慢慢规范起来)

现在类的外部使用者再也不能直接访问修改mstrGender变量了,但是我们还是希望外部访问者能获取性别方面的信息,那该怎么弄呢?我们需要学习类模块中的两个新技能:Public Property Get / Public Property Let (还有一个类似的技能 Public Property Set 会在将来介绍)

Public是公有的意思,有了它,类的外部使用者才能访问。Property是属性的意思。Get是获取,Let是赋值。所以 Public Property Get是获取类的某个属性,Public Property Let是给某个属性赋值。我们修改Person类的代码如下:

Option Compare Database
Option Explicit

Public Name As String
Private mstrGender As String
Public Situation As String

Public Sub Speak()
    Select Case Situation
        Case "一般"
            MsgBox Left(Name, 1) & "小姐"
        Case "正式"
            MsgBox Left(Name, 1) & "女士"
        Case "撩"
            MsgBox "小姐姐"
        Case Else
            MsgBox Name
    End Select
End Sub

Private Sub Class_Initialize()
    Situation = "一般"
End Sub

Public Property Get Gender() As String
    Gender = mstrGender
End Property

Public Property Let Gender(lstrGender As String)
    If mstrGender = "" Then
        mstrGender = lstrGender
    Else
        MsgBox "性别一旦设定,就无法修改"
    End If
End Property

25-27行的代码,为类定义了一个获取性别(Gender)的属性。我们直接将类的私有变量mstrGender的值直接返回给访问者。

29-35行的代码,为类定义了一个设置性别(Gender)值的属性。(参数“lstr”中的“l”代表List,参数列表的意思)当你给性别赋值的时候,首先会检查mstrGender的值是否为空字符串,如果是,就直接赋值。如果不是,说明之前已经被赋值过了,就弹出对话框提示你不能修改。(实际项目中,一般不会用对话框来提示类的使用者,而是通过触发一个事件的方式来与类的使用者做信息的传递。)这样,性别属性就不再让类的外部使用者随意修改了。你只能为性别赋值一次,你可以叫这种属性为“只写一次属性”。

我们来看看类的使用效果,在模块1中,我们修改代码如下:

Option Compare Database
Option Explicit

Sub test()
    Dim objperson As Person
    Set objperson = New Person
    
    objperson.Name = "赵冰冰"
    objperson.Gender = "女"
    objperson.Speak
    
    MsgBox "修改前性别:" & objperson.Gender
    objperson.Gender = "男"
    MsgBox "修改后性别:" & objperson.Gender
End Sub

第12行和14行代码都是获取性别属性,第13行代码是对性别属性赋值。我们运行一下该代码,会依次弹出4个对话框

通过这种方式来定义类的属性,我们既能够保护类的私有变量不受到外部使用者的随意修改,也能够提供在我们允许的情况下访问和修改类属性的途径。

作为一个有经验的Access VBA开发人员,如果你掌握了这种定义类属性的方式,你可以开更多的脑洞,比如,如果在类中,将Public Property Get去掉,只保留Public Property Let会怎么样?或者反过来,将Public Property Let去掉,只保留Public Property Get又会怎么样?另外,29-35行代码,严格来讲,不能称之为“只写一次属性”,如果你第一次将性别赋值为空字符串””,那么你第二次还能再赋值。如果要设计一个真正的“只写一次属性”,你该怎么做?这些问题先留给有钻研精神的你思考吧。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注