Implementing Interfaces

 <  Day Day Up  >  

A type implements an interface by specifying the name of the interface in an Implements statement. There is no limit on the number of interfaces that a type can implement; a type can implement multiple interfaces in a single Implements statement or can contain multiple Implements statements. For example, the following code defines two classes, Square and Rectangle , which each implement the ISizeable interface and the IComparable interface.

 Class Square   Implements ISizeable, IComparable   ... End Class Class Rectangle   Implements ISizeable   Implements IComparable   ... End Class 

When a type implements an interface, it must provide an implementation for each member of the interface. A type implements a member of an interface by adding an Implements clause on a type member that has the same signature (i.e., parameter list and return type) as the interface member. In the following example, the Square class provides an implementation for each member of the ISizeable interface.

 Class Square   Implements ISizeable   Private _Height, _Width As Integer   Public ReadOnly Property Height() As Integer _       Implements ISizeable.Height     Get       Return _Height     End Get   End Property   Public ReadOnly Property Width() As Integer _       Implements ISizeable.Width     Get       Return _Width     End Get   End Property   Public Sub Resize(ByVal NewWidth As Integer, _       ByVal NewHeight As Integer) Implements ISizeable.Resize     _Height = NewHeight     _Width = NewWidth     RaiseEvent Resized(NewWidth, NewHeight)   End Sub   Public Event Resized(ByVal NewWidth As Integer, _     ByVal NewHeight As Integer) Implements ISizeable.Resized End Class 

It is worth noting that the name of a member and the name of the interface member that it implements do not have to match, although they usually do. For example, the previous example could have been written instead as follows .

 Class Square   Implements ISizeable   Private _Height, _Width As Integer   Public ReadOnly Property SquareHeight() As Integer _       Implements ISizeable.Height     Get       Return _Height     End Get   End Property   Public ReadOnly Property SquareWidth() As Integer _       Implements ISizeable.Width     Get       Return _Width     End Get   End Property   Public Sub SquareResize(ByVal NewWidth As Integer, _       ByVal NewHeight As Integer) Implements ISizeable.Resize     _Height = NewHeight     _Width = NewWidth     RaiseEvent SquareResized(NewWidth, NewHeight)   End Sub   Public Event SquareResized(ByVal NewWidth As Integer, _     ByVal NewHeight As Integer) Implements ISizeable.Resized End Class 

The fact that the Square.SquareHeight method and the ISizeable.Height method have different names makes no difference when you are implementing the interface. It does affect how the type and interface are used, as will be discussed in a subsequent section.

Style

Because it can be confusing to consumers of the type to have two names for the same method, it is generally best to use the same names when you are implementing an interface.


Private Interface Implementation

One thing to note is that the members of an interface are always Public even if the members implementing them are not. In other words, interface methods on a type can be called even if the members implementing them cannot be called ( assuming , of course, that the type itself is accessible). For example, the following class implements the ISizeable interface in such a way that the ISizeable methods can only be called through the interface.

 Class Square   Implements ISizeable   Private _Height, _Width As Integer   Private ReadOnly Property Height() As Integer _       Implements ISizeable.Height     Get       Return _Height     End Get   End Property   Private ReadOnly Property Width() As Integer _       Implements ISizeable.Width     Get       Return _Width     End Get   End Property   Private Sub Resize(ByVal NewWidth As Integer, _       ByVal NewHeight As Integer) Implements ISizeable.Resize     _Height = NewHeight     _Width = NewWidth     RaiseEvent Resized(NewWidth, NewHeight)   End Sub   Private Event Resized(ByVal NewWidth As Integer, _     ByVal NewHeight As Integer) Implements ISizeable.Resized End Class Module Test   Sub Main()     Dim s As Square = New Square()     Dim i As ISizeable = s     ' Error: Resize is not accessible     s.Resize(10, 10)     ' OK: Resize is always accessible through interface     i.Resize(10, 10)   End Sub End Module 

In the previous example, the Square class uses a private interface implementation to implement the ISizeable interface without exposing any of the interface methods directly. Private interface implementations are useful when a type wishes to implement an interface but not expose the methods as a part of the type. A common use of private interface implementation is to implement a general interface while providing a more specific version of the interface's methods. For example, a Point structure may implement the IComparable interface (which takes Object ) while exposing a CompareTo method that takes Point values.

 Structure Point   Implements IComparable   Private Function CompareTo(ByVal obj As Object) As Integer _       Implements IComparable.CompareTo     ...   End Function   Public Function CompareTo(ByVal p As Point) As Integer     ...   End Function   ... End Structure 

In this example, the CompareTo(Object) function is less desirable than the CompareTo(Point) method because converting a Point structure to Object would require boxing. However, there is still benefit in implementing the IComparable interface, since many Framework methods use it. A private interface implementation allows implementing the interface while only exposing the strongly typed CompareTo to code using the Point class directly.

Event Implementation

When a type implements an interface event, the delegate type of the event in the interface must match the delegate type of the event in the type. When the delegate type is stated explicitly, this is relatively straightforward.

 Interface IClickable   Event Click As EventHandler End Interface Class Square   Implements IClickable   Event Click As EventHandler Implements IClickable.Click End Class 

However, when an event implicitly defines its own delegate, things get more complicated. An event that implements an interface event but doesn't explicitly declare its delegate type picks up its delegate type from the interface event.

 Interface IClickable   Event Click As EventHandler End Interface Class Square   Implements IClickable   Event Click(ByVal sender As Object, ByVal e As EventArgs) _     Implements IClickable.Click End Class 

In this example, the Square.Click event implicitly picks up its delegate type from IClickable.Click . So the underlying delegate type of Square.Click will be System.EventHandler and not an auto-generated ClickEventHandler type. Note that the parameters to the event still must match the arguments of the event delegate.

If an event attempts to implement two events that use different delegate types, an error will occur because there is no way for an event to have two different delegate types.

 Interface IClickable   Event Click(ByVal sender As Object, ByVal e As EventArgs)   Event Release(ByVal sender As Object, ByVal e As EventArgs) End Interface Class Square   Implements IClickable   ' Error, delegate types conflict   Event Click(ByVal sender As Object, ByVal e As EventArgs) _     Implements IClickable.Click, IClickable.Release End Class 

Even though IClickable.Click and IClickable.Release have the same parameters, they each declare their own implicit delegate type. When Square.Click attempts to implement both of the events, it cannot choose between the two delegate types, so an error results.

 <  Day Day Up  >  


The Visual Basic .NET Programming Language
The Visual Basic .NET Programming Language
ISBN: 0321169514
EAN: 2147483647
Year: 2004
Pages: 173
Authors: Paul Vick

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net