一般来说,属性是关于某个对象的数据,而方法则是该对象可能被要求去执行的动作。有些的属性比较明显,比如 Color 和 Name,而另一些则明显的是方法,比如 Move 和 Show。
不过,就跟人类行为的各个方面一样,这里也存在一个界限不清的区域,在该区域一个参数可作为二者之中的任一个。
例如,为什么 Visual Basic 的 Collection 类的 Item 方法是一种方法而不是一种索引属性呢?该集合中的这些项不恰恰是数据吗?一个设想的 Widgets 集合类的 Item 方法可能以任一种方式实现,如下所示:
' Widgets
集合中对象的私有存储(这对于两种实现方法来说是相同的)。Private mcol As New Collection
Public Property Get Item(Index As Variant) As Widget
Set Item = mcol.Item(Index)
End Function
-
或-
Public Function Item(Index As Variant) As Widget
Set Item = mcol.Item(Index)
End Function
这两种实现并非完全大相径庭。二者都是只读的,因此为了把 Widget 对象放到集合中,二者都依赖于 Widgets 类的 Add 方法。二者都将每一件事情委派给 Collection 对象去做—甚至它们的错误也都由该 Collection 产生的!
详细信息 关于委派,在本章的后面的“代码重用的许多(内部)方面”和“创建自己的集合类”中作了解释。
在想方设法搞清某个成员是对象的数据,还是对象的行为的过程中,可能会真地变得吹毛求疵。例如,可能会争辩说那个 Item 是一种方法,因为该集合的确是在做什么事—浏览所需要的 Widget。不过,这种论点通常对任何一种实现来说,都是有道理的。
可能会发现将这种论点转向其头部,并问问自己想怎样看待这些成员,这样会更有用一些。如果希望人们把它当作关于对象的数据来看待,就使之成为一种属性。如果希望人们把它作为对象所做的什么事情来看待,就使之成为一种方法。
用属性过程来实现成员的一个很强的理由,依赖于想要在代码中使用该成员的方式。也就是说,允许 Widgets 集合的用户象下面这样编写代码吗?
Set Widgets.Item(4) = wdgMyNewWidget
如果允许的话,那么就以读写属性来实现该成员(用“Property Get”和“Property Set”),因为方法不支持这种语法。
注意 在所碰到的大多数集合实现中,这种语法是不允许的。为集合实现 Property Set 并不象看起来那么容易。
也可以暂时假定对象象一个控件。能想象到成员在“属性”窗口中,或者在某个属性页上显示吗?如果那样做并没有任何意义的话,就不要作为一种属性来实现该成员。
已经将某个 Item 设置为只读的属性后,如果忘记了这一点,并试图将一个值赋给它,很可能就会发现 Visual Basic 为某个 Property Get 所产生的错误信息—“不能给只读属性赋值”,这跟为某个 Function 过程所产生的错误信息-“赋值号左边的函数调用必须返回变体或对象”相比较,理解起来要更容易一些。
作为最后一招,往上抛硬币来作出决定。如果在本节主题中的其它参数看起来都不是那么让人确信的话,那么它就可能没有多大意义。
详细信息 属性过程是在本章前面的“向类中添加属性”引入的。而方法则在“向类中添加方法”作了讨论。