深入VBS类与对象

来源:互联网 发布:炫踪网络发行的游戏 编辑:程序博客网 时间:2024/05/16 15:55
VBS也可以编写类:

1.VBS的类有两种事件:

(1)Initialize 事件,在创建类的实例时发生(新建)此事件。

Private Sub Class_Initialize()
    statements
End Sub

当类初始化时,statements部分由零个或多个将要运行的代码语句组成。

(2)Terminate 事件,在所关联的类的实例终止(销毁)时发生此事件。

Private Sub Class_Terminate()
    statements
End Sub

当类初始化时,statements 部分由零个或多个将要运行的代码语句组成。

下面是类事件的例子:

  1. Class TestClass
  2.   Private Sub Class_Initialize   ' 设置 Initialize 事件。
  3.     MsgBox("TestClass started")
  4.   End Sub
  5.   Private Sub Class_Terminate   ' 设置 Terminate 事件。
  6.     MsgBox("TestClass terminated")
  7.   End Sub
  8. End Class

  9. Set X = New TestClass   ' 创建一个 TestClass 实例。
  10. Set X = Nothing      ' 删除实例。
复制代码
摘要:
a.类的事件方法格式是固定的,事件名是固定的,事件只能是Sub不能是Function,事件无参数;
b.类实例通过New来创建,通过Nothing来销毁;
c.记住所有的类实例都是对象,创建与销毁时记得用Set语句,没有Set是错的
d.这两个事件都不是必须的,即编写类时可以不提供这两个事件的实现代码;
e.这两个事件作用比较大,可以在这两个事件中初始化对象以及销毁对象时做一些其他的工作
f.因为VBS的两个类事件都不接受参数,所以不能在用New创建对象时初始化对象,可以另外设置一个公有的过程来完成这个任务

2.类可以有公有和私有字段:
(1)公有的字段可以外部访问,私有的不能:
(2)可以定义数组字段,且此数组字段可以是动态数组

3.类可以有公有或者私有的属性:
(1)公有的属性可以外部调用,私有的属性不能
(2)用Property Get定义读属性,用Property Set和Property Let来定义写属性
(3)当定义写属性时,如果此属性封装的是对象字段,则此写属性必须是Property Set
(4)属性不必是成对出现,这样就可以造成只读或只写属性,当然Private任意一方也可以造成这种情况

4.类可以有公有和私有的方法:
(1)公有的方法可以外部调用,私有的方法不能
  1. Class Circle
  2.             Public r
  3.         
  4.             Private mArea
  5.         
  6.             Public Sub Init(a)
  7.                         r=a
  8.             End Sub

  9.             Public Function Area()
  10.                         If mArea="" Then mArea=Atn(1)*4*r*r
  11.                         Area=mArea
  12.             End Function
  13.         
  14.             Private Sub EchoInfo()
  15.                         MsgBox "圆的半径是:" & r & vbCrLf & "圆的面积是:" & mArea
  16.             End Sub
  17.         
  18. End Class

  19. Set c = New Circle   ' 创建一个 TestClass 实例。
  20. c.Init 2                                
  21. 'Init是在Python中的构造函数名称,你可以定义其他的名称,随你喜欢
  22. '其他语言,如C#,C++都是用类名做为构造函数名称,显然没有Init简单易记
  23. MsgBox c.r
  24. MsgBox c.Area()
  25. 'MsgBox c.mArea                        
  26. '无法访问,因为这个字段是私有的,只能类内部访问,如上面的Area方法
  27. 'MsgBox c.EchoInfo()        
  28. '无法访问,因为这个方法是私有的,只能类内部访问

  29. Set c = Nothing      ' 删除实例
复制代码
下面是与属性相关的例子:
  1. Class Student
  2.         Private mAge,mName,mNumber,mSex,mLover,mYear,mRank
  3.         '这里字段最好都定义为私有的,这样可以更强的控制字段的读写
  4.         '并可以在读写时提供一些其他的计算处理
  5.         '这里我们假设Lover(情侣)也是一个学生,那么此字段就是一个
  6.         '对象类型的字段,请留意它的属性是怎么实现的
  7.         Dim Belief   '人生信条,这里不指定其可访问性
  8.         Sub Init(namestr,sexstr,ageint,rankint)
  9.                 If mName="" Then '这个判断可以确保实例只被初始化一次
  10.                         mName=namestr
  11.                         mSex=sexstr
  12.                         mAge=ageint
  13.                         mRank=rankint
  14.                         Randomize
  15.                         mNumber=Int(Rnd*10000+1)
  16.                         mYear=Year(Date)
  17.                         '这里没有提供mLover字段的初始化,毕竟一见钟情太少
  18.                 Else
  19.                         MsgBox "No,you can't initialize a instance twice"
  20.                 End If
  21.         End Sub
  22.         
  23.         Property Get Rank()
  24.                 Rank=mRank
  25.         End Property
  26.         
  27.         Property Let Rank(value)
  28.                 mRank=value
  29.         End Property
  30.         '这里的写属性只能是Property Let,不能是Property Set,因为在外部要赋值给属性的是一个int型的
  31.         '是值类型,不是对象类型(常说的引用类型)所以不能用Set,外部赋值时也不能用Set语句
  32.         
  33.         Property Get Age()
  34.                 If mYear<Year(Date) Then
  35.                         mYear=Year(Date)
  36.                         mAge=mAge+1
  37.                 End If
  38.                 age=mAge
  39.         End Property
  40.         'Age一经设置只会随着年份增加而改变,毕竟人们生活于同一个时空
  41.         
  42.         Public Default Property Get Name()
  43.                 Name=mName
  44.         End Property
  45.         '学生姓名默认是不能更改,当然你也可以改名字,建议在类中定义
  46.         '保守的改名方法
  47.         '这里定义Name为默认属性,注意使用Default关键字定义默认属性时,必须有Public关键字
  48.         
  49.         Property Get Sex()
  50.                 Sex=mSex
  51.         End Property
  52.         '学生性别当然,一经初始化,不会更改,除非蛋疼得跑去变性
  53.         
  54.         Property Get Lover()
  55.                 Set Lover=mLover
  56.         End Property
  57.         
  58.         Property Set Lover(value)
  59.                 Set mLover=value
  60.         End Property
  61.         '有Set属性,此子(女)真风流,如果你专情,不妨Private它
  62.         '这里写成Property Let也是可以的,不过后面Set stu1.Lover=stu2要把Set去掉
  63.         '由此例可以看出Property Let和Property Get定义的属性内部定义都一样的Set语句,但是在外部
  64.         '时,如果上面这里定义的是Let属性那么不能用Set语句来赋值,虽然赋值给Lover属性的是一个
  65.         '引用类型(即对象类型),如果上面这里是定义的是Set属性,则必须Set语句
  66.         
  67.         '由以上Lover和Rank两个属性知,我们可以得出这样的结论:
  68.         '(1)无论是对引用类型字段的封装,还是对值类型字段的封装,都可以用Property Let,而Set
  69.         '只能在对引用类型字段封装时出现
  70.         '(2)定义类时我们可以根据外部赋值到属性的类型来决定用Set还是用Let,而后定义好了之后,再由
  71.         '定义的是Property Let还是Property Set来决定赋值方式,即用不用Set语句
  72.        
  73.         Function IsGay()
  74.                 If Lover.Sex=Sex Then
  75.                         IsGay=True
  76.                 Else
  77.                         IsGay=False
  78.                 End If
  79.         End Function

  80.         Function Info()
  81.                 Info="学生信息:" & vbCrLf & _
  82.                                 "学号:" & mNumber & vbCrLf & _
  83.                                 "姓名:" & mName & vbCrLf & _
  84.                                 "性别:" & mSex & vbCrLf & _
  85.                                 "年龄:" & Age & vbCrLf & _
  86.                                 "排名:" & mRank & vbcrlf & _
  87.                                 "情侣:" & mLover
  88.         End Function
  89.         '这之中Age通过属性来获取以确保每次获取的是正确的年龄
  90.         '没有定义Age的写属性,这样就保护了字段,避免非法改写
  91.         '外部只能通过Age的读属性来访问,所以确保了外部读取年龄的正确性
  92.         '对mLover.Name可以直接用mLover来输出,因为它的Name属性是默认属性
  93. End Class

  94. Dim stu1,stu2                                       
  95. '最好定义变量,这样可以防止全局变量对自定义函数的影响
  96. Set stu1=New Student
  97. Set stu2=New Student
  98. stu1.Init "Jobs","BigBoy",23,13        
  99. 'stu1.Age=32               
  100. '这里运行会报错,因为没有定义Age的写属性,外部无法通过赋值修改年龄
  101. stu2.Init "Joliy","Girl",21,10
  102. Set stu1.Lover=stu2
  103. MsgBox stu1.Info     '可访问,说明方法隐式为Public
  104. stu1.Rank=8            '可访问,说明属性隐式为Public
  105. stu1.Belief="No pains,no gains"
  106. MsgBox stu1.Belief    '可访问,说明字段隐式为Public
  107. MsgBox "使用默认属性:" & vbcrlf & stu1 & vbcrlf & stu2
  108. Set stu1=Nothing
  109. Set stu2=Nothing
复制代码

摘要:
1.使用Default关键字定义默认属性时,必须显式指定属性为Public,虽然隐含的属性就是Public
2.在对象构造函数中设置条件,以确保初始化只能进行一次
3.(1)无论是对引用类型字段的封装,还是对值类型字段的封装,都可以用Property Let,而Property Set
   只能在对引用类型字段封装时出现,而且这种情况下依然可以不用Property Set
   (2)定义类时我们可以根据外部赋值到属性的类型来决定用Set还是用Let,因为如果要赋值
   给属性的值的类型是值类型,那么无论如何也用不着Property Set;而后定义好了之后,可以再由
   定义的是Property Let还是Property Set来决定赋值方式,即用不用Set语句
4.关于类中元素的可访问性:
   (1)属性不作说明时被认为是Public的,但定义Default时必须显式指定Public
   (2)方法与字段在不显式指定其可访问性时,被认为是Public的
   (3)由下面这个例子知,类仅有的两个事件也可以不指定可访问性,隐式也被认为是Public,可以外调
  1. Class TestClass
  2.   Sub Class_Initialize   ' 设置 Initialize 事件。
  3.     MsgBox("TestClass started")
  4.   End Sub
  5.   Sub Class_Terminate   ' 设置 Terminate 事件。
  6.     MsgBox("TestClass terminated")
  7.   End Sub
  8. End Class

  9. Set X = New TestClass   ' 创建一个 TestClass 实例。
  10. x.Class_Initialize         '可正常运行
  11. Set X = Nothing      ' 删除实例。
复制代码


注意:上面的例子中,即使把第12句去掉,Class_Terminate事件仍然会发生,它会在脚本终止前被解释器触发。


关于VBS类中的多参数的Property Let和Property Set:

    Class Twitter                       Private mName,mMessage                       Public Sub Init(pName)                    If mName<>"" Then mName=pName            End Sub                       Property Get Message(width)                    Message=mMessage            End Property                       Property Let Message(width,value)                    mMessage=Left(value,width)            End Property                       Property Get Name                    Name=mName            End Property    End Class    Set libai=New Twitter    libai.Init "李白"    libai.Message(5)="hello world!"    MsgBox libai.Message(5)    Set t=Nothing

关于VBS类中的动态数组字段:

    Class Twitter                        Private mName,mMessages(),mNextIndex                        Public Sub Init(pName)                    If mName<>"" Then                            mName=pName                            ReDim mMessages(0)                            mNextIndex=0                    End If            End Sub                        Property Get Messages(number)                    If number>=mNextIndex Then                            Messages="Sorry,the number of messages in your twitter is less than " & number                    Else                            Messages="The first " & number & " messages are:"                            For i=0 To number-1                                    Messages=Messages & vbCrLf & vbCrLf & mMessages(i)                            Next                    End If            End Property                        Property Let Messages(number,value)                    For i=1 To number                            ReDim Preserve mMessages(mNextIndex)                            mMessages(mNextIndex)=value                            mNextIndex=mNextIndex+1                    Next            End Property                        Property Get Name                    Name=mName            End Property    End Class    Set libai=New Twitter    libai.Init "李白"    libai.Messages(3)="Hello world!"    libai.Messages(3)="This is a test!"    libai.Messages(5)="VBScript is a good script tool!"    MsgBox libai.Messages(5)    MsgBox libai.Messages(20)    Set libai=Nothing

但是下面这个:

    Class Twitter                        Private mName,mMessages()                        Public Sub Init(pName)                    If mName<>"" Then                            mName=pName                            ReDim mMessages(0)                    End If            End Sub                        Property Get Messages(number)                    If number>=ubound(mMessages) Then                            Messages="Sorry,the number of messages in your twitter is less than " & number                    Else                            Messages="The first " & number & " messages are:"                            For i=0 To number-1                                    Messages=Messages & vbCrLf & vbCrLf & mMessages(i)                            Next                    End If            End Property                        Property Let Messages(number,value)                    For i=1 To number                            mMessages(ubound(mMessages))=value                            redim preserve mMessages(ubound(mMessages)+1)                    Next            End Property                        Property Get Name                    Name=mName            End Property    End Class

它竟然出错了......


由上面的Init我们已经Redim了一次,现在mMessages字段的最大下标应该是0,但是,这个状态似乎并没有被保存下来,在其它块对它进行访问时,就出错了..


所以这里对于动态数组类型的字段,似乎不同块之间对它的修改的最后一个空元素不会被很好的保存。。。


5.Me关键字:

只有公有的成员才可以使用Me来进行引用

原创粉丝点击