Training
Certifications
Books
Special Offers
Community




 
OOP with Microsoft® Visual Basic® .NET and Microsoft Visual C#™ .NET Step by Step
Author Robin A. Reynolds-Haertle
Pages 416
Disk 1 Companion CD(s)
Level All Levels
Published 01/23/2002
ISBN 9780735615687
ISBN-10 0-7356-1568-3
Price(USD) $39.99
To see this book's discounted price, select a reseller below.
 

More Information

About the Book
Table of Contents
Sample Chapter
Index
Related Series
Related Books
About the Author

Support: Book & CD

Rate this book
Barnes Noble Amazon Quantum Books

 


Chapter 9: Providing Services Using Interfaces



Chapter 9   Providing Services Using Interfaces

In this chapter, you'll learn how to

  • Create an interface.
  • Implement an interface that you created.
  • Implement the IComparable interface.
  • Implement the IEnumerable and IEnumerator interfaces.
  • Implement the IFormattable interface.
  • Use an inner class.
In Chapters 5 and 6, you used inheritance to make new classes out of existing classes. When classes are related by inheritance, you can refer to a derived instance through a base reference value. This polymorphic behavior isn't limited to derived classes. Visual Basic .NET and Visual C# provide another construct, the interface, that also behaves polymorphically. In the Microsoft .NET Framework, interfaces are commonly used to provide services for a class. The interface can support something your object can do, but that service doesn't fall into the is-a relationship found in inheritance.

An IMoveable Interface

An interface is like an abstract class with all abstract members. The interface serves as a contract that defines what methods, properties, and events a class must implement. In this chapter, you'll create an interface, implement it in a class, and use the class polymorphically through an interface reference.

Your first task is to create an IMoveable interface and implement it in a Pawn class. This interface might be useful if you were moving objects around as part of a game. The classes in the the project can be so different that they aren't related by inheritance, but they do share the ability to be moved around. The IMoveable interface provides a standard interface for relocating objects. This interface is described in the following UML diagram:

Click to view graphic
Click to view graphic

This diagram introduces a new UML element for an interface. Technically, the property, as the construct that contains a get and a set method, isn't supported by UML. In earlier exercises, I've used the upper section of the class diagram, called the attributes section, to specify the properties. The attributes section contains the data members of a case, which often have a one-to-one correspondence with the properties. Other languages don't have the property construct and thus list the private data members in the attributes section, while the get and set methods are shown in the methods section. The property construct fits nicely with the attributes section in a class element, but this correspondence breaks down in the case of an interface element because the interface element, as defined by the UML, doesn't have an attribute section. Because interfaces carry no implementation, they don't have instance data, only methods. So to fit the property concept into the UML interface, the getters and setters are shown as Get and Set methods. The IMoveable interface contains two properties, X and Y, and a Move method that takes two parameters for direction (up, down, left, right) and distance.

The following diagram is a shorthand style of representing interfaces in UML. This style is used more commonly than the extended version shown previously.

Click to view graphic
Click to view graphic

Define the IMoveable interface

This short example is a console application rather than a Windows application. The output of the program appears in the command prompt window. The interface defines the location of the object as X and Y properties and includes a Move method for moving the object around.

  1. On the File menu, point to New, and then click Project.
  2. Click Visual Basic or Visual C# in the Project Types tree.
  3. In the Templates list, click Console Application.
  4. Name the application MoveIt, and click OK.
  5. On the Project menu, click Add New Item.
  6. In the Add New Item dialog box, click Code File in the Templates list, name the new file IMoveable.vb or IMoveable.cs, and click Open.
  7. Add the following code to declare the IMoveable interface. If you're using Visual C#, add a namespace declaration so that the IMoveable interface is in the same namespace as the other classes in the project.
  8. ' Visual Basic
    Public Interface IMoveable
    End Interface
     
    // Visual C#
    namespace MoveIt {
        public interface IMoveable {
        }
    }

  9. Add an enumeration to indicate which direction the object is to move. Add this enumeration immediately before the interface. Although Visual Basic allows the definition of nonpublic enumerations inside the interface, Visual C# does not.
  10. ' Visual Basic
    Public Enum Direction
        Up
        Down
        Left
        Right
    End Enum
     
    // Visual C#
    public enum Direction { Up, Down, Left, Right };

  11. Add the two property declarations to the interface definition. The public keyword isn't allowed in interface definitions. The purpose of the interface is to define what methods, properties, and events a class will support. Private members don't make sense in this context. The Visual Basic definition allows the Readonly and Writeonly modifiers of properties. In the case of Visual C#, you need to show which of the accessors need to be implemented.
  12. ' Visual Basic
    Property X() As Integer
    Property Y() As Integer
     
    // Visual C#
    int X {
        get;
        set;
    }
     
    int Y {
        get;
        set;
    }

  13. Add the Move declaration to the interface:
  14. ' Visual Basic
    Sub Move(ByVal aDirection As Direction, ByVal howFar As Integer)
     
    // Visual C#
    void Move(Direction direction, int howFar);

The interface is complete. To make it usable, you need to implement the interface in a class.

Implement the IMoveable interface in the Pawn class

In the Pawn class, you implement the X and Y properties and the Move method.

  1. On the Project menu, click Add Class. Name the new class Pawn.
  2. Modify the class to indicate that it will implement the IMoveable interface.
  3. ' Visual Basic
    Public Class Pawn
        Implements IMoveable
    End Class
     
    // Visual C#
    public class Pawn : IMoveable {
    }

    Visual C# uses the same syntax for declaring base classes and interfaces. Visual Basic uses the Implements keyword to indicate the interfaces of a class. Notice that after you type the Implements keyword, IntelliSense displays a list of interfaces. The icon next to the interface name is similar to the UML symbol.

    Click to view graphic
    Click to view graphic

  4. If you're using Visual Basic, click IMoveable in the Class Name list. In the Method Name list, click Move. The declaration for the Move method is added to the class. Repeat this procedure for the X and Y properties of IMoveable.
  5. If you're using Visual C#, in the Class View, expand the Pawn class and Bases And Interfaces. Right-click the IMoveable interface in the Class View, point to Add, and then click Implement Interface on the shortcut menu. The declarations for all the members are added to the class. In addition, the code is enclosed in region statements that make that section of code collapsible.

  6. Add a field for the X property, and implement the X property:
  7. ' Visual Basic
    Private m_x As Integer = 0
    Public Property X() As Integer Implements MoveIt.IMoveable.X
        Get
            Return m_x
        End Get
        Set(ByVal Value As Integer)
            m_x = Value
        End Set
    End Property
     
    // Visual C#
    private int m_x;
    public int X {
        get { return m_x; }
        set { m_x = value; }
    }

    Notice that Visual Basic uses the Implements keyword again to specify which interface member is being implemented. The Implements keyword is followed by the qualified name of the method. The fully qualified name takes the form Namespace.ClassName.MemberName. Unless you have added a namespace declaration or changed the default project properties, the namespace is the same as the project name. The Visual C# compiler makes the determination without the special keyword by using the signature.

    You don't use the Overrides or override keyword when you're implementing the interface member. The code isn't overriding a base class member. The interface is strictly a contract about what will be found in the class interface.

  8. Add a field for the Y property, and implement the Y property. For Visual Basic, you add the keyword Implements and the qualified name of the member implemented. In Visual C#, the compiler matches the class method to the interface method.
  9. ' Visual Basic
    Private m_y As Integer = 0
    Public Property Y() As Integer Implements MoveIt.IMoveable.Y
        Get
            Return m_y
        End Get
        Set(ByVal Value As Integer)
            m_y = Value
        End Set
    End Property
     
    // Visual C#
    private int m_y;
    public int Y {
        get { return m_y; }
        set { m_y = value; }
    }

  10. Add code for the Move method:
  11. ' Visual Basic
    Public Sub Move(ByVal aDirection As MoveIt.Direction, ByVal howFar _
    As Integer) Implements MoveIt.IMoveable.Move
        Select Case aDirection
            Case Direction.Up
                m_y += howFar
            Case Direction.Down
                m_y -= howFar
            Case Direction.Left
                m_x -= howFar
            Case Direction.Right
                m_x += howFar
        End Select
    End Sub
     
    // Visual C#
    public void Move(Direction direction, int howFar) {
        switch (direction) {
            case Direction.Up :
                m_y += howFar;
                break;
            case Direction.Down :
                m_y -= howFar;
                break;
            case Direction.Left :
                m_x -= howFar;
                break;
            case Direction.Right :
                m_x += howFar;
                break;
            }
    }

  12. Add one method to the Pawn class that's not part of the IMoveable interface:
  13. ' Visual Basic
    Private m_captured As Boolean = False
    Public Property Captured() As Boolean
        Get
            Return m_captured
        End Get
        Set(ByVal Value As Boolean)
            m_captured = Value
        End Set
    End Property
     
    // Visual C#
    private bool m_captured = false;
    public bool Captured {
        get { return m_captured; }
        set { m_captured = value; }
    }

That completes the implementation of the IMoveable interface in the Pawn class.

Test the IMoveable interface

When you created the project as a console application, Visual Studio .NET created a start-up method. Now you add code to that method to test the Pawn class.

  1. If you're using Visual Basic, double-click Module1.vb in the Solution Explorer to open the file in the code editor.
  2. If you're using Visual C#, double-click Class1.cs in the Solution Explorer to open the file in the code editor.

  3. Add code to the Main method. Note that mover is declared as IMoveable yet instantiated as Pawn. You can't instantiate an interface; it does not have implementation.
  4. ' Visual Basic
    Sub Main()
        Dim mover As IMoveable = New Pawn()
        mover.X = 10
        mover.Y = 10
        Console.WriteLine("X:{0}  Y:{1}", mover.X, mover.Y)
        Console.WriteLine("Moving up 5 spaces.")
        mover.Move(Direction.Up, 5)
        Console.WriteLine("X:{0}  Y:{1}", mover.X, mover.Y)
     
        Dim aPawn As Pawn = CType(mover, Pawn)
        Console.WriteLine("Is the pawn captured? {0}", aPawn.Captured)
    End Sub
     
    // Visual C#
    static void Main(string[] args)
        IMoveable mover = new Pawn();
        mover.X = 10;
        mover.Y = 10;
        Console.WriteLine("X:{0}  Y:{1}", mover.X, mover.Y);
        Console.WriteLine("Moving up 5 spaces.");
        mover.Move(Direction.Up, 5);
        Console.WriteLine("X:{0}  Y:{1}", mover.X, mover.Y);
     
        Pawn pawn = (Pawn)mover;
        Console.WriteLine("Is the pawn captured? {0}", pawn.Captured);
    }

    Using a reference to an interface is similar to using a reference to a base class. The reference variable mover has access only to the members of IMoveable, though you can set it to refer to an instance of Pawn. To access the Pawn members of the mover reference, you must cast the reference to Pawn. In a larger application, the mover reference could be pointing to some other game piece, such as a King or a Queen. As you type the code, look closely at the IntelliSense lists to see these differences.

  5. Press Ctrl+F5 to run the program. If you press F5, the output flashes briefly. Running the program with Ctrl+F5 gives you a chance to examime the output. Here's the output:
  6. Click to view graphic
    Click to view graphic


Next



Last Updated: January 12, 2002
Top of Page