有时,部件的对象需要不受部件用户干涉地完成对象之间的通信。例如,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 关键字声明属性过程。事实上,组成同一属性的不同的属性过程其范围也不同。前面的代码示例可以用一对属性过程重写:
'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 程序员指南》“用对象编程”中介绍。