Previous section   Next section

6.4 Abstract Methods and Classes

Each type of Window has a different shape and appearance. Drop-down list boxes look very different from Buttons. Clearly, every subclass of Window should implement its own DrawWindow( ) method—but so far, nothing in the Window class enforces that they must do so. To require subclasses to implement a method of their base, you need to designate that method as abstract.

You designate a method as abstract by placing the MustOverride keyword at the beginning of the method definition, as follows:

MustOverride Public Sub DrawWindow ( )

An MustOverride method has no implementation. It creates a method name and signature that must be implemented in all derived classes. Furthermore, making one or more methods of any class MustOverride has the side effect of making the class abstract; an abstract class must be marked with the keyword MustInherit.

Classes marked with MustInherit establish a base for derived classes, but it is not legal to instantiate an object of a class marked MustInherit. Once you declare a method with MustOverride, you prohibit the creation of any instances of that class.

If one or more methods of the class are MustOverride, the class definition must be marked MustInherit, as in the following:

MustInherit Public Class Window

Thus, if you were to designate DrawWindow( ) MustOverride in the Window class, the Window class would thus become MustInherit. Then you could derive from Window, but you could not create any Window objects/instances. If the Window class is an abstraction, there is no such thing as a Window object; only objects derived from Window.

Making Window.DrawWindow( ) MustOverride means that each class derived from Window would have to implement its own DrawWindow( ) method. If the derived class failed to implement the MustOverride method, that derived class would also be MustInherit, and again no instances would be possible. Example 6-3 illustrates the use of MustInherit and MustOverride.

The Idea Behind Abstraction

MustInherit classes should not just be an implementation trick; they should represent the idea of an abstraction that establishes a "contract" for all derived classes. In other words, MustInherit classes mandate the public methods of the classes that will implement the abstraction.

The idea of a MustInherit Window class ought to lay out the common characteristics and behaviors of all windows, even though you never intend to instantiate the abstraction Window itself.

A MustInherit class serves to implement the abstraction "Window" that will be manifest in the various concrete instances of Window, such as browser window, frame, button, list box, drop-down, and so forth. The MustInherit class establishes what a Window is, even though we never intend to create a "Window" per se. An alternative to using MustInherit is to define an interface, as described in Chapter 8.

Example 6-3. An abstract class and method
Option Strict On
Imports System

MustInherit Public Class Window
   
   ' constructor takes two integers to
   ' fix location on the console
   Public Sub New(top As Integer, left As Integer)
      Me.top = top
      Me.left = left
   End Sub 'New
  
   ' simulates drawing the window
   ' notice: no implementation
   Public MustOverride Sub DrawWindow( )
   
   Protected top As Integer
   Protected left As Integer

End Class 'Window

' ListBox derives from Window
Public Class ListBox

   Inherits Window
   
   ' constructor adds a parameter
   Public Sub New(top As Integer, left As Integer, contents As String)
      MyBase.New(top, left) ' call base constructor
      
      listBoxContents = contents
   End Sub 'New
   
   
   ' an overridden version implementing the abstract method
   Public Overrides Sub DrawWindow( )
      
      Console.WriteLine("Writing string to the listbox: {0}", listBoxContents)
   End Sub 'DrawWindow
   
   Private listBoxContents As String ' new member variable

End Class 'ListBox

Public Class Button

   Inherits Window
   
   Public Sub New(top As Integer, left As Integer)
      MyBase.New(top, left)
   End Sub 'New
   
   ' implement the abstract method
   Public Overrides Sub DrawWindow( )
      Console.WriteLine("Drawing a button at {0}, {1}" + ControlChars.Lf, top, left)
   End Sub 'DrawWindow

End Class 'Button

Public Class Tester
   
   Shared Sub Main( )
      Dim winArray(3) As Window
      winArray(0) = New ListBox(1, 2, "First List Box")
      winArray(1) = New ListBox(3, 4, "Second List Box")
      winArray(2) = New Button(5, 6)
      
      Dim i As Integer
      For i = 0 To 2
         winArray(i).DrawWindow( )
      Next i
   End Sub 'Main

End Class 'Tester

Output:
Writing string to the listbox: First List Box
Writing string to the listbox: Second List Box
Drawing a button at 5, 6

In Example 6-3, the Window class has been declared MustInherit and therefore cannot be instantiated. If you replace the first array member:

winArray(0) = New ListBox(1, 2, "First List Box")

with this code:

winArray(0) = New Window(1, 2)

the program will generate the following error:

C:\...Module1.vb(63): 'New' cannot be used on class 'DebuggingVB.Window' because it 
contains a 'MustOverride' member that has not been overridden.

You can instantiate the ListBox and Button objects because these classes override the MustOverride method, thus making the classes concrete (i.e., not abstract).


  Previous section   Next section
Top