Imagine that you are the author of a Document class. It turns out that Document objects can be stored in a database, so you decide to have Document implement the IStorable interface. To do so, you must do two things:
To declare that the class implements the interface, you use the keyword Implements on the line below the class definition: Public Class Document Implements IStorable Visual Studio 2005 will help you with the available interfaces , as shown in Figure 18-7. As soon as you write that your class implements the IStorable interface, Visual Studio 2005 will fill in all the required methods and properties of the interface, as shown in Figure 18-8! Figure 18-7. IntelliSense helping find the interfaceFigure 18-8. IntelliSense stubs out all the interface methods and propertiesAll you have to do is fill in the stubbed out methods and properties and the Interface contract is fulfilled. You cannot create an instance of an interface; instead you instantiate a class that implements the interface. The class implementing the interface must fulfill the contract exactly and completely. Document must provide both a Read and a Write method and the Status property. How it fulfills these requirements, however, is entirely up to the Document class. Although IStorable dictates that Document must have a Status property, it does not know or care whether Document stores the actual status as a member variable, or looks it up in a database. The details are up to the implementing class. 18.23.1. Implementing More Than One InterfaceClasses can derive from only one class, but can implement any number of interfaces. When you design your class, you can choose not to implement any interfaces, you can implement a single interface, or you can implement two or more interfaces. For example, you might have a second interface: ICompressible for files that can be compressed to save disk space. If your Document class can be stored and it also can be compressed, you might choose to implement both the IStorable and ICompressible interfaces.
To do so, you change the declaration (in the base list) to indicate that both interfaces are implemented, separating the two interfaces with commas: Public Class Document Implements ICompressible, IStorable Once you've done this, your Document class must also implement the methods specified by the ICompressible interface: Public Sub Compress( ) Implements ICompressible.Compress Console.WriteLine("Implementing Compress") End Sub 'Compress Public Sub Decompress( ) Implements ICompressible.Decompress Console.WriteLine("Implementing Decompress") End Sub 'Decompress All of this is illustrated in Example 18-5. Example 18-5. Demonstrating interfacesModule Module1 Sub Main( ) Dim doc As New Document("Test Document") doc.Status = -1 doc.Read( ) doc.Compress( ) Console.WriteLine("Document Status: {0}", doc.Status) End Sub End Module Interface IStorable Sub Read( ) Sub Write(ByVal obj As Object) Property Status( ) As Integer End Interface 'IStorable ' here's the new interface Interface ICompressible Sub Compress( ) Sub Decompress( ) End Interface 'ICompressible ' Document implements both interfaces Public Class Document Implements ICompressible, IStorable ' the document constructor Public Sub New(ByVal s As String) Console.WriteLine("Creating document with: {0}", s) End Sub 'New ' implement IStorable Public Sub Read( ) Implements IStorable.Read Console.WriteLine("Implementing the Read Method for IStorable") End Sub 'Read Public Sub Write(ByVal o As Object) Implements IStorable.Write Console.WriteLine( _ "Implementing the Write Method for IStorable") End Sub 'Write Public Property Status( ) As Integer Implements IStorable.Status Get Return myStatus End Get Set(ByVal Value As Integer) myStatus = Value End Set End Property ' implement ICompressible Public Sub Compress( ) Implements ICompressible.Compress Console.WriteLine("Implementing Compress") End Sub 'Compress Public Sub Decompress( ) Implements ICompressible.Decompress Console.WriteLine("Implementing Decompress") End Sub 'Decompress ' hold the data for IStorable's Status property Private myStatus As Integer = 0 End Class 'Document Output: Creating document with: Test Document Implementing the Read Method for IStorable Implementing Compress Document Status: -1 18.23.2. Casting to an InterfaceYou can access the members of the IStorable interface through the Document object, as if they were members of the Document class: Dim doc As New Document("Test Document") doc.Status = -1 doc.Read( ) Alternatively, you can create a reference to an object that implements an interface, and then use that interface to access the methods: Dim isDoc As IStorable = doc isDoc.status = 0 isDoc.Read( ) You will, from time to time, create collections of objects that implement a given interface (e.g., a collection of IStorable objects). You may manipulate them without knowing their real type; so long as they all implement IStorable. Similarly, you can declare a method to take an IStorable as a parameter, and you can pass in any object that implements IStorable. As stated earlier, you cannot instantiate an interface directly. That is, you cannot write: IStorable isDoc as New IStorable( ) You can, however, create an instance of the implementing class, and then create an instance of the interface: Dim isDoc as IStorable = doc; This is considered a widening conversion (from Document to the IStorable interface), so the compiler makes it work with no need for an explicit cast. |