Handling Events Inheritance Classes

66

2.14.4 Handling Events

When a field is of an object type that exposes events, the fields enclosing class may define methods for handling those events. For an explanation of events, see Sect ion 2.20 later in this chapter. Here is an example: Imports System.Data.SqlClient Public Class EventHandlingTest Private WithEvents m_cn As SqlConnection Public Sub MySqlInfoMessageEventHandler _ ByVal sender As Object, _ ByVal e As SqlInfoMessageEventArgs _ Handles m_cn.InfoMessage Dim sqle As SqlError For Each sqle In e.Errors Debug.WriteLinesqle.Message Next End Sub ... End Class This class has a field, m_cn, that holds a database connection. The field is declared with the WithEvents keyword, so the class is capable of receiving and handling events raised by the Connection object. In order to handle the Connection objects InfoMessage event, the class defines a method having the appropriate parameter list and a Handles clause: Public Sub MySqlInfoMessageEventHandler _ ByVal sender As Object, _ ByVal e As SqlInfoMessageEventArgs _ Handles m_cn.InfoMessage This declaration signifies that when the InfoMessage event is raised by the object referenced in m_cn, the MySQLInfoMessageEventHandler method should be called to handle it. The body of the event handler in this case simply outputs the messages received from SQL Server.

2.14.5 Inheritance

Inheritance is one way to reuse and extend previously written code. A programs design often requires several classes as variations of a common theme. Consider a drawing program that deals with many shapes. Such a program would probably define a class for each kind of shape. However, there would be much in common among such classes, including many of their fields, methods, and events. Inheritance allows these common features to be extracted into a base class from which the various specific shape classes are derived. Ex am ple 2- 7 shows a base class called Shape, two utility classes used by Shape Point and Extent, and two classes derived from Shape Circle and Square. Example 2-7. Class inheritance This structure represents a point on a plane. Public Structure Point Public X As Integer Public Y As Integer End Structure 67 This structure represents a size or offset. Public Structure Extent Public XExtent As Integer Public YExtent As Integer End Structure This class represents the functionality that is common for all shapes. This class cant itself be instantiated, because of the MustInherit modifier. Public MustInherit Class Shape The upper-left corner of the shape. Public Origin As Point The width and height of the shape. Public Size As Extent This forces all derived classes to implement a method called Draw. Notice that a method marked with MustInherit has no body in the base class. Public MustOverride Sub Draw This subroutine moves a shape. Public Sub OffsetByVal Amount As Extent Origin.X += Amount.XExtent Origin.Y += Amount.YExtent End Sub This property allows the class user to find or set the center of a shape. Public Property Center As Point Get Dim retval As Point retval.X = Origin.X + Size.XExtent \ 2 retval.Y = Origin.Y + Size.YExtent \ 2 Return retval End Get Set Dim currentCenter As Point = Center Origin.X += Value.X - currentCenter.X Origin.Y += Value.Y - currentCenter.Y End Set End Property End Class Public Class Circle Inherits Shape Public Overrides Sub Draw Just a dummy statement for the example. Console.WriteLineCircle.Draw was called. End Sub End Class Public Class Square Inherits Shape Public Overrides Sub Draw Just a dummy statement for the example. Console.WriteLineSquare.Draw was called. End Sub 68 End Class Note the following: • The MustInherit modifier in the Shape class declaration indicates that this class cant be instantiated—it can only be used as a base class in a derivation. In object-oriented design terminology, such a class is known as an abstract class. • The Circle and Square classes inherit the public members declared in the Shape class. • Using the MustOverride modifier on the Draw method declaration in the Shape class forces derived classes to provide an implementation for this method. • Constructors arent inherited. The Ellipse and Rectangle classes therefore declare their own constructors. When no constructor is explicitly provided in a class definition, the compiler automatically creates one. Therefore, all classes have at least one constructor. The autogenerated constructor also known as the default constructor created by the compiler is the same as if the following code were written in the class definition: Public Sub New MyBase.New End Sub That is, the default constructor simply calls the base classs parameterless constructor. If there is no parameterless constructor on the base class, the compiler generates an error. If a class defines a parameterized constructor, the compiler does not generate a default constructor. Therefore, if both parameterless and parameterized constructors are needed, both must be explicitly written in the class definition. It is possible to define a class from which it is not possible to inherit. This is done with the NotInheritable keyword in the class declaration, as shown here: Public NotInheritable Class SomeClass ... End Class

2.14.6 Methods