对象之间的私有通信

有时,部件的对象需要不受部件用户干涉地完成对象之间的通信。例如,Widgets 集合类可能要为新创建的 Widget 设置 Parent 属性,并将其设为只读。

类的公共方法可以被其它对象调用,也可以被客户端调用。私有方法则不能从部件外调用,且它对于部件内的其它对象也是不可见的。

解决办法是使用 Friend 方法。下面的代码段中,假想的 Widget 对象显露一个公共的只读 Parent 属性,以及一个 Widgets 集合用来为新创建的 Widget 设置其 Parent 属性的 Friend 方法(称为 SetParent)。

'Widget 总是 mechanism 的组成部分。
Private mmchParent As Mechanism

Public Property Get Parent() As Mechanism
   Set Parent = mmchParent
End Property

Friend Sub SetParent(ByVal NewParent As Mechanism)
   Set mmchParent = NewParent
End Sub

如果一个方法用 Friend 关键字声明,则它对部件中的其它对象是可见的,但该方法不会添加到类型库或公共接口。图 6.4 说明了这一点。

图 6.4   Friend 方法的工程范围

运行时,从 Widgets 集合类(工程内)见到的接口与从客户端见到的接口是不同的。工程内(以及编译好的 DLL )Widget 接口包括 Widgets 集合可调用的 Friend 方法 SetParent。

因为 Friend 方法没有被添加到类型库,所以客户端只能见到 Widget 的接口中的公共属性和方法。

对属性使用 Friend 关键字

也可以使用 Friend 关键字声明属性过程。事实上,组成同一属性的不同的属性过程其范围也不同。前面的代码示例可以用一对属性过程重写:

'Widget  mechanism 的组成部分。
Private mmchParent As Mechanism

Public Property Get Parent() As Mechanism
   Set Parent = mmchParent
End Property

Friend Property Set Parent(ByVal NewParent As _
      Mechanism)
   Set mmchParent = NewParent
End Sub

在部件内,Parent 是一个可读/写的属性。对于客户端,它是只读属性,这是因为部件的类型库中只出现 Property Get。

可以认为 Friend 具有介于 Public 和 Private 之间的范围。

重点   要调用 Friend 方法和属性,必须使用严格定义类型的对象变量。在上面的示例中,Widgets 集合为能够访问 SetParent 方法或 Property Set Parent,必须使用声明为 As Widget 的变量。不能从声明为 As Object 的变量中调用 Friend 方法。

隐藏返回私有对象的对象属性

“使用属性和集合创建对象模型”描述了对象模型中私有对象的使用方法。在对象模型中,这种对象与公共对象链接时,可以使用 Friend 关键字来声明属性过程的所有部分。

例如,每一个 Widget 对象都可能具有 Socket 对象,而该 Socket 对象出于某种原因不能显露给部件的用户。可以把下面的对象属性添加到该 Widget 对象。这样,不必将该属性添加到类型库或公共接口,就可以在部件内访问该 Socket:

'创建所需 Socket 对象 (As New)Private msoc As New Socket

Friend Property Get Socket() As Socket
   Set Socket = msoc
End Property

详细信息   Friend 方法在《Visual Basic 程序员指南》“用对象编程”中介绍。