Visual Basic Concepts
There may be circumstances in which you want your component’s objects to be able to communicate with each other, without interference from users of your component. For example, you might want your Widgets collection class to set the Parent property of a newly created Widget, and thereafter to have Parent be read-only.
Public methods on a class can be called by other objects, but they can also be called by clients. Private methods cannot be called from outside the component, but neither are they visible to other objects within your component.
The solution is to use Friend methods. In the following code fragment, the hypothetical Widget object exposes a public read-only Parent property, and a Friend method (called SetParent) that the Widgets collection can use to set the value of the Parent property after creating a new Widget.
' A Widget is always part of a 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
When a method is declared with the Friend keyword, it’s visible to other objects in your component, but is not added to the type library or the public interface. This is illustrated in Figure 6.4.
Figure 6.4 Friend methods have project scope
At run time, the Widgets collection class (within the project) sees a different interface from that seen by clients. The view of the Widget’s interface within the project (and the compiled DLL) includes the Friend method SetParent, which the Widgets collection calls.
The client only sees the public properties and methods of the Widget’s interface, because Friend methods are not added to the type library.
You can also declare property procedures with the Friend keyword. In fact, the different property procedures that make up a property can have different scope. Thus the earlier code example can be rewritten as a pair of property procedures:
' A Widget is always part of a 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
From within the component, Parent is a read/write property. To clients, it’s a read-only property, because only the Property Get appears in the component’s type library.
You can think of Friend as a different scope, halfway between Public and Private.
Important In order to invoke Friend methods and properties, you must use strongly typed object variables. In the example above, the Widgets collection must use a variable declared As Widget in order to access the SetParent method or the Property Set Parent. You cannot invoke Friend methods from variables declared As Object.
"Using Properties and Collections to Create Object Models" describes the use of private objects in object models. When linking such objects to the public objects in the object model, you can declare all parts of the property procedure using the Friend keyword.
For example, each Widget object might have Socket object, which for some reason you don’t want to expose to users of your component. You could add the following object property to the Widget object, so that from inside your component you could access the Socket, without adding the property to the type library or the public interface:
' Create the Socket object on demand (As New).
Private msoc As New Socket
Friend Property Get Socket() As Socket
Set Socket = msoc
End Property
For More Information Friend methods are introduced in "Programming with Objects," in the Visual Basic Programmer’s Guide.