Implementing Interfaces

The most common operation with interfaces that you will want to perform is implementation. You indicate that you want to implement an interface similar to the way you did so in VB6. The way to implement the members of an interface has changed. Let's take a look at implementing the IDrawable interface (see Listing 2.6). A synopsis follows the listing.

Listing 2.6. Implementing the IDrawable Interface
1:  Imports System.Drawing
2:
3:  Public Class Form1
4:      Inherits System.Windows.Forms.Form
5:
6:  [ Windows Form Designer generated code ]
7:
8:    Private Sub Draw(ByVal DrawableObject As IDrawable)
9:      DrawableObject.Draw(CreateGraphics)
10:   End Sub
11:
12:   Private Sub Button1_Click(ByVal sender As System.Object, _
13:     ByVal e As System.EventArgs) Handles Button1.Click
14:
15:     Dim S As New GraphicString()
16:     S.Text = "Visual Basic .NET Power Coding"
17:     S.Location = New PointF(10, 150)
18:     Draw(S)
19:
20:     Dim B As New GraphicButton()
21:     B.Location = New Point(10, 10)
22:     B.Size = New Size(75, 50)
23:     Draw(B)
24:
25:   End Sub
26: End Class
27:
28: Public Interface IDrawable
29:   Sub Draw(ByVal G As Graphics)
30: End Interface
31:
32: Public Class GraphicString
33:
34:   Implements IDrawable
35:   Private FText As String
36:   Private FLocation As PointF
37:
38:   Public Property Text() As String
39:     Get
40:       Return FText
41:     End Get
42:     Set(ByVal Value As String)
43:       FText = Value
44:     End Set
45:   End Property
46:
47:   Public Property Location() As PointF
48:   Get
49:     Return FLocation
50:   End Get
51:   Set(ByVal Value As PointF)
52:     FLocation = Value
53:   End Set
54:   End Property
55:
56:   Public Sub Draw(ByVal G As Graphics) _
57:     Implements IDrawable.Draw
58:
59:     G.DrawString(FText, New Font("Courier", 20), _
60:       Brushes.Blue, FLocation)
61:
62:   End Sub
63:
64: End Class
65:
66: Public Class GraphicButton
67:   Implements IDrawable
68:
69:   Private FLocation As Point
70:   Private FSize As Size
71:
72:   Public Property Location() As Point
73:   Get
74:     Return FLocation
75:   End Get
76:   Set(ByVal Value As Point)
77:     FLocation = Value
78:   End Set
79:   End Property
80:
81:   Public Property Size() As Size
82:   Get
83:     Return FSize
84:   End Get
85:   Set(ByVal Value As Size)
86:     FSize = Value
87:   End Set
88:   End Property
89:
90:   Public Sub Draw(ByVal G As Graphics) _
91:     Implements IDrawable.Draw
92:
93:     ControlPaint.DrawButton(G, New Rectangle(FLocation, FSize), _
94:       ButtonState.Normal)
95:
96:   End Sub
97: End Class

Lines 1 through 26 implement the Form1 class. When Button1 is clicked, one instance each of GraphicButton and GraphicString are created. Each of these objects implements IDrawable; as a result, they can be passed to a method that accepts any object that implements IDrawable (see lines 8 through 10).

Lines 28 through 30 define the IDrawable interface. The contract stipulates that any class implementing this interface must define one method, Draw, which is defined to take a single Graphics object.

Lines 32 through 64 define the GraphicString class, and lines 66 through 97 define the GraphicButton class. Both classes implement IDrawable. GraphicString has String and Point properties, and GraphicButton has Size and Point properties. GraphicString implements IDrawable.Draw on lines 56 through 62, and GraphicButton implements IDrawable.Draw on lines 90 through 96.

The Implements statements at the beginning of the GraphicString and GraphicButton classes indicate that these two classes accept the IDrawable contract and will implement Draw. The Implements clauses in the Draw methods in the GraphicString and GraphicButton classes complete the requirements of the contract. (You indicate that a method is implementing an interface method by adding Implements interface.membername at the end of the method, where interface is the actual name of the interface and membername is the name of the member you are implementing. In our example, Implements IDrawable.Draw indicates that these methods are implementing the interface method.)

In Visual Basic .NET you can call the interface method directly or through a reference to the interface, as we did in line 9 of Listing 2.6.

Adding Properties to an Interface

You can add properties to interfaces by declaring the property header only. When you implement the interface, you define a property in the class implementing the interface and add an Implements clause to the end of the property header. If we want to extend IDrawable to include a Point property named Location, we can use the following code.

Public Interface IDrawable
  Sub Draw(ByVal G As Graphics)
  Property Location() As Point
End Interface

After we have extended the contract this way, consumers of this version of IDrawable would have to implement the Location property too. A suitable implementation (by itself; just copy the following code to a class) might appear as demonstrated next.

Public Property Location() As Point Implements IDrawable2.Location
  Get
    Return FLocation
  End Get
  Set(ByVal Value As Point)
    FLocation = Value
  End Set
End Property

In the revision the Implements clause is all we need to make this the implementation of the Location property, and FLocation is presumed to be a field in the containing class.

Adding Events to an Interface

Extending our theme, we could add an event to the IDrawable interface. Perhaps we might like to let a consumer know that the Draw method has been invoked. If we add an OnDraw PaintEventHandler event, consumers of our interface could raise this event when the Draw method is called. The code fragment that follows demonstrates the addition of the PaintEventHandler event.

Public Interface IDrawable

  Property Location() As Point
  Sub Draw(ByVal G As Graphics)
  Event OnDraw As PaintEventHandler

End Interface

The preceding interface adds the event to the interface. The following code could be copied and pasted into a class that implements the IDrawable interface. (I have included the revised Draw method to demonstrate how the event might be raised.)

Public Sub Draw(ByVal G As Graphics) _
  Implements IDrawable.Draw

  G.DrawEllipse(Pens.Red, GetRect())
  DoDraw(G)

End Sub

Public Event OnDraw As PaintEventHandler _
 Implements IDrawable.OnDraw

Private Function GetRect() As Rectangle
  Return New Rectangle(FLocation.X, FLocation.Y, _
    FSize.Width, FSize.Height)
End Function

Private Sub DoDraw(ByVal G As Graphics)
  RaiseEvent OnDraw(Me, New PaintEventArgs(G, GetRect()))
End Sub

The Draw method literally performs the Draw operation. (In the example we are drawing an ellipse using GDI+.) Before the Draw operation exits we invoke a DoDraw method. Following convention, DoDraw raises the event for us. The implementation of the OnDraw event follows the Draw method, and GetRect and DoDraw are added for convenience.

The only code we had to add to support the IDrawable contract was code for Draw, Location, and OnDraw. The rest of the code was added for convenience. For example, GetRect was reused to ensure that the boundaries for drawing and drawing from DoDraw are identical.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.198.60