Section 13.7. Overriding Interface Implementations

   

13.7 Overriding Interface Implementations

An implementing class is free to mark any or all of the methods that implement the interface as overridable. Derived classes can then override or provide new implementations. For example, a Document class might implement the IStorable interface and mark the Read( ) and Write( ) methods as overridable. The Document might Read( ) and Write( ) its contents to a File type. The developer might later derive new types from Document, such as perhaps a Note or EmailMessage type. While the Document class implements Read( ) and Write to save to a File, the Note class might implement Read( ) and Write( ) to read from and write to a database.

Example 13-5 strips down the complexity of the previous examples and illustrates overriding an interface implementation. In this example, you'll derive a new class named Note from the Document class.

Document implements the IStorable-required Read( ) method as an overridable method, and Note overrides that implementation.

Notice that Document does not mark Write( ) as overridable. You'll see the implications of this decision in the analysis section that follows the output.

The complete listing is shown in Example 13-5 and analyzed in detail following.

Example 13-5. Overriding an interface implementation
 Option Strict On Imports System Imports Microsoft.VisualBasic Namespace OverridingInterfaces     Interface IStorable         Sub Read( )         Sub Write( )     End Interface     ' Simplify Document to implement only IStorable     Public Class Document : Implements IStorable         ' the document constructor         Public Sub New(ByVal s As String)             Console.WriteLine("Creating document with: {0}", s)         End Sub  ' Make read virtual   Public Overridable Sub Read( ) Implements IStorable.Read   Console.WriteLine("Document Virtual Read Method for IStorable")   End Sub    ' NB: Not virtual!   Public Sub Write( ) Implements IStorable.Write   Console.WriteLine("Document Write Method for IStorable")  End Sub     End Class     ' Derive from Document     Public Class Note : Inherits Document         Public Sub New(ByVal s As String)             MyBase.New(s)             Console.WriteLine("Creating note with: {0}", s)         End Sub  ' override the Read method   Public Overrides Sub Read( )    Console.WriteLine("Overriding the Read method for Note!")   End Sub    ' implement my own Write method   Public Shadows Sub Write( )   Console.WriteLine("Implementing the Write method for Note!")  End Sub     End Class     Class Tester         Public Sub Run( )             ' Create a Document object             Dim theNote As Document = New Note("Test Note")             ' cast the Document to IStorable             If TypeOf theNote Is IStorable Then                 Dim isNote As IStorable = theNote                 isNote.Read( )                 isNote.Write( )             End If             Console.WriteLine(vbCrLf)             ' direct call to the methods             theNote.Read( )             theNote.Write( )             Console.WriteLine(vbCrLf)             ' create a note object             Dim note2 As New Note("Second Test")             ' Cast the note to IStorable             If TypeOf note2 Is IStorable Then                 Dim isNote2 As IStorable = note2                 isNote2.Read( )                 isNote2.Write( )             End If             Console.WriteLine(vbCrLf)             ' directly call the methods             note2.Read( )             note2.Write( )         End Sub         Public Shared Sub Main( )             Dim t As New Tester( )             t.Run( )         End Sub     End Class End Namespace 
  Output:  Creating document with: Test Note Creating note with: Test Note Overriding the Read method for Note! Document Write Method for IStorable Overriding the Read method for Note! Document Write Method for IStorable Creating document with: Second Test Creating note with: Second Test Overriding the Read method for Note! Document Write Method for IStorable Overriding the Read method for Note! Implementing the Write method for Note! 

In Example 13-5, the IStorable interface is simplified for clarity's sake:

 Interface IStorable     Sub Read( )     Sub Write( ) End Interface 

The Document class implements the IStorable interface:

 Public Class Document : Implements IStorable 

The designer of Document has opted to make the Read( ) method overridable but not to make the Write( ) method overridable:

 Public  Overridable  Sub Read( ) Implements IStorable.Read Public Sub Write( ) Implements IStorable.Write 

In a real-world application, you would almost certainly mark both as overridable, but I've differentiated them to demonstrate that the developer is free to pick and choose which methods can be overridden.

The new class, Note, derives from Document:

 Public Class Note : Inherits Document 

It is not necessary for Note to override Read( ) (it may shadow it instead), but it is free to do so and has done so here:

 Public Overrides Sub Read( ) 

To illustrate the implications of marking an implementing method as overridable, the Run( ) method calls the the Read( ) and Write( ) methods in four ways:

  • Through the base class reference to a derived object

  • Through an interface created from the base class reference to the derived object

  • Through a derived object

  • Through an interface created from the derived object

As you'll see, the base class reference and the derived class reference act just as they always have: overridable methods are implemented polymorphically and nonoverridable methods are not. The interfaces created from these references work just like the references themselves : overridable implementations of the interface methods are polymorphic, and nonoverridable methods are not.

The one surprising aspect is this: when you call the nonpolymorphic Write( ) method on the IStorable interface cast from the derived Note, you actually get the Document's Write( ) method. This is because Write( ) is implemented in the base class and is not overridable.

To accomplish the first two calls, a Document (base class) reference is created, and the address of a new Note (derived) object created on the heap is assigned to the Document reference:

 Dim theNote As Document = New Note("Test Note") 

An interface reference is created and the Note is cast to the IStorable interface:

 If TypeOf theNote Is IStorable Then     Dim isNote As IStorable = theNote 

You then invoke the Read( ) and Write( ) methods through that interface. The output reveals that the Read( ) method is responded to polymorphically and the Write( ) method is not, just as you would expect:

 Overriding the Read method for Note! Document Write Method for IStorable 

The Read( ) and Write( ) methods are then called directly on the derived object itself:

 theNote.Read( ) theNote.Write( ) 

and once again you see the polymorphic implementation has worked:

 Overriding the Read method for Note! Document Write Method for IStorable 

In both cases, the Read( ) method of Note was called, but the Write( ) method of Document was called.

To prove to yourself that this is a result of the overriding method, you next create a second Note object, this time assigning its address to a reference to a Note. This will be used to illustrate the final cases (i.e., a call through a derived object and a call through an interface created from the derived object):

 Dim note2 As New Note("Second Test") 

Once again, when you cast to a reference, the overridden Read( ) method is called. When, however, methods are called directly on the Note object:

 note2.Read( ) note2.Write( ) 

the output reflects that you've called a Note and not an overridden Document:

 Overriding the Read method for Note! Implementing the Write method for Note! 
   


Learning Visual Basic. NET
Learning Visual Basic .Net
ISBN: 0596003862
EAN: 2147483647
Year: 2002
Pages: 153
Authors: Jesse Liberty

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