暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

类属性只能赋值一次的设置

VBA语言専攻 2022-02-08
97
【分享成果,随喜正能量】尊重现实,尊重客观,改良浮躁,放掉幻想,每个人都注定成为自己。不管经过了多少岁岁年年,保持对生活的创造力、崭新力、重塑力,就是自我人生最好的格局。
《VBA中类的解读及应用》教程是我推出的第五套教程,目前已经是第一版修订了。这套教程定位于最高级,是学完初级,中级后的教程。
类,是非常抽象的,更具研究的价值。随着我们学习、应用VBA的深入,有必要理解这些抽象的理论知识。对象,类,过程,方法,属性,事件,接口,接口如何实现等等。掌握了这些理论,不仅对于VBA这种寄生语言的实质有所深入的理解,也对自然界的很多事物将同样有所感悟。目前,这套教程程序文件已经通过32位,64位两种office系统测试。
这套教程共两册,八十四讲,今后一段时间会给大家陆续推出修订后的教程内容。今日的内容是:类属性只能赋值一次的设置

第三十二讲 类属性只能赋值一次的真正实现----“二师兄”的成长历程之四

各位朋友好,我们今天继续关注二师兄的成长之路。在上一讲中,我们讲了用Property Get 和 Property Let(set)定义类的属性,这样可以获得更多的灵活性,在我们的类pigsy中有Gender(性别)属性使用了这种定义方式,本讲,我们将继续完善其他类的属性,同时给大家揭示更多关于类的属性方面更深层次的问题。虽然有一定的难度,我尽可能把这些内容以非常容易的方式讲解给大家。

1  Name(姓名)属性 

我们将它的声明按照Gender属性的方式从Public(公有)改为Private(私有),同时使用变量命名规则将Name改名为myName。如下的代码:
Private myName as String
有了这样的一个私有模块级变量后,我们就有了一个存储属性数据的宿主(或者称之为容器)接下来,我们要定义Name(姓名)的读取属性(Property Get)
Public Property Get Name() As String
    Name = myName
End Property
其实这里代码的意义就是将宿主myName中的数据传递给Name的过程。
接下来我们为Name(姓名)定义赋值属性(Property Let)。设计之前,我们要考虑下,是否要对Name赋值的时候,做任何约束。比如,是否要检查一下赋值的有效性?一般中国人的姓名都在4个字以下,对超过4个字的情况,是否要弹出错误提示框?另外,姓名被赋值一次后,是否允许再被第二次赋值?这些都是在设计之前要考虑的问题。这里我们就只检查一下超过4个字的情况。
       Public Property Let Name(lnName As String)
    If Len(lnName) <= 4 Then
        myName = lnName
    Else
        MsgBox "姓名不能超过4个字符"
    End If
End Property
代码截图:
代码的解析:上述代码为name属性赋值,赋值是将一个变量传递进来,所以我用了lnName这样的变量作为传入的数据,传入数据后我要对数据进行校验。如果校验通过,那么将传进来的数据放到宿主中,以便在读取的时候取出。如果不通过则提示给用户信息。

2  添加一个DOB(出生日期Day Of Birth)属性

为了让我们的pigsy类更加接近现实,我们给它添加另外一个日期类的属性:DOB是指出生日期(Day Of Birth的缩写)。同样我们定义一个变量(大家要记住这个变量是宿主,或者叫容器,目的就是为了在类模块中装一下数据)如下
Private myDOB As Date
我们顺便可以考虑一下上节我们提到的“只赋值一次”的问题,考虑给出生日期定义赋值属性,这里,我们要实施真正的“只赋值一次”。我们不能依赖myDOB的值去判断是否已经赋过值了,因为我们可以赋一个零值。在实际项目中,我们要使用布尔(Boolean)变量作为是否赋过值的标志(Flag)。
出生日期的赋值属性定义如下:
Public Property Let DOB(lnDOB As Date)
    Static myFlag As Boolean
    If myFlag = False Then
myFlag = True
      myDOB = lnDOB
    End If
End Property
代码解析:我们使用静态(Static)布尔变量myFlag作为一个开关,所有布尔变量的初始值都为否(False),所以第一次给出生日期赋值的时候,myFlag为False,判断条件myFlag=False获得通过,紧接着将这个开关的值设置为True,然后将新的出生日期赋值给模块级的私有变量宿主myDOB。第二次给出生日期赋值的时候,静态变量myFlag的值是True,判断条件myFlag=False就不再能通过了。这样就彻底的保证了出生日期属性只能写一次。

l特别注意点:这里必须使用静态变量,因为一般的变量在赋值子程序执行完毕后,值就被丢弃了。静态变量能将值一直保留在内存中,直到整个类对象被释放为止。

出生日期的赋值属性搞定以后,我们来考虑一下它的读取属性。我们读取一个日期,很多情况下,都是需要把它显示出来,日期的显示有很多的格式,例如2019年7月22日,2020年07月22日,2019-7-2,2020/7/2,2019/07/02等等。我们可以在读取属性的同时将它的显示格式也确定下来。我们用字符串类型来返回读取属性。

3  实际代码的应用及解读

代码如下:
Public Property Get DOBA() As String
    DOBA = Format(myDOB, "YYYY年mm月dd日")
End Property


代码解读:看到我上面的代码,细心的朋友会发现,老师,怎么又多了一个DOBA的属性啊?对的,我们特意增加的,那么为什么不直接用DOB这个属性呢?这个问题在本讲的最后会给大家以解答,这里可以先思考一下。
这里DOB和DOBA就是两个不同名字的属性,它们都是围绕着类的私有变量myDOB来读写。DOB只定义成赋值属性,只能出现在赋值号(=)左边,否则的话,编译报错:属性的无效使用。DOBA定义成了读取属性,只能出现在赋值号(=)右边,否则的话,编译报错:不能给只读属性赋值。我们也可以将DOB理解为只写属性,DOBA理解为只读属性。这样对于上一讲的内容关于使用Property Get 和 Property Let(set)的灵活性方面,这讲也进行了讲解。好了,我们下一讲继续。

今日内容回向:
1  如何设置真正的“只赋值一次”的属性?
2  为什么要引入DOBA的属性呢?


本讲内容参考程序文件:VBA-CLASS(32-33).xlsm




我20多年的VBA实践经验,全部浓缩在下面的各个教程中
【分享成果,随喜正能量】不迎合他人的期待,只追寻自己的热爱,她是持续突破自我的音乐创作者。金典携手品牌代言人@李宇春 ,邀你一起,跟着自然的节奏,找到自己的节拍,在生活的舞台,活出你要的自在。
文章转载自VBA语言専攻,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论