Implementing multiple interfaces


The CBugFilter class presented earlier implemented the IFilter interface. You could access the IFilter interface or the default _CBugFilter interface through separate object variables. Think about this for a moment. If you can get two interfaces through polymorphism, why not three interfaces? Why not 12? Why not 137 interfaces?


No problem.


Consider the CJumpHop class. It implements two interfaces: IHop and IJump. Here’s IHop:

‘ IHop interface
Function Hop() As String
End Function

You can probably guess the IJump interface:

‘ IJump interface
Function Jump() As String
End Function

The CJumpHop class implements both of these interfaces:

‘ CJumpHop class
Implements IJump
Implements IHop

Private Function IHop_Hop() As String
IHop_Hop = “Hop”
End Function

Private Function IJump_Jump() As String
IJump_Jump = “Jump”
End Function

You can access the implementation of either interface through an appropriate object variable:

Dim h As IHop, j As IJump
Set h = New CJumpHop
Debug.Print h.Hop
Set j = h
Debug.Print j.Jump

You can access the Hop method polymorphically through the h object variable or you can access the Jump method polymorphically through the j object variable. Notice also that you can get at the IJump interface through an IHop object variable (Set j = h).


You could extend the CJumpHop class to have members of its own:

‘ Additional methods belonging to CJumpHop
Function Skip() As String
Skip = “Skip”
End Function

Function Hop() As String
Hop = IHop_Hop
End Function

Function Jump() As String
Jump = IJump_Jump
End Function

These methods aren’t polymorphic. They belong directly to the class and can be used like this:

Dim j As New CJumpHop
Debug.Print jh.Skip
Debug.Print jh.Hop
Debug.Print jh.Jump

Notice that the Hop and Jump methods simply delegate to the polymorphic versions so that the CJumpHop class can have non-polymorphic versions without doing any work. The Hop method and the IHop_Hop method are separate methods accessible through different parts of the object, but they share the same implementation code.


This probably looks like a whole lot of nothing, and with interfaces this simple, it is. But imagine that you have a collection of graphical objects—stars, polyhedrons, ovals, and so on. There’s a separate class for each kind of object, but the classes all implement the same interfaces. The IDrawable interface has methods and properties for setting the position and color of the shape object, and for drawing it. The IScaleable interface has methods and properties for scaling the objects to different sizes. The IMangleable interface has methods and properties for twisting and skewing the object. Now let’s say you have a collection of these objects, and you want to draw the ones that are scaleable. You might do it something like this:

Dim scaleable As IScaleable, drawable As IDrawable, shape As CShape
On Error Resume Next
For Each shape In shapes
Set scaleable = shape
‘ An error indicates that the shape isn’t scaleable
If Err = 0 Then
scaleable.Scale Rnd
Set drawable = shape
drawable.Color = QBColor(GetRandom(1, 15))
drawable.X = GetRandom(0, pbShapes.Width)
drawable.Y = GetRandom(0, pbShapes.Height)
drawable.Draw pbShapes
End If
Next
On Error Goto 0

Like most air code, this snippet is probably full of bugs and errors, but I’m sure you could make it work. In fact, there’s an example that does something very similar with multiple interfaces on the Visual Basic CD.