Section 9.5. Time Class Case Study: Overloaded Constructors


9.5. Time Class Case Study: Overloaded Constructors

Like methods, constructors of a class can be overloaded. To do so, provide a separate method declaration with the same name (New) for each version of the method but different numbers, types and/or orders of parameters.

Class Time with Overloaded Constructors

The Time constructor in Fig. 9.1 initialized hourValue to 12 and minuteValue and secondValue to 0 (i.e., noon) with a call to the class's SetTime method. Recall that the declaration in line 4 of Fig. 9.2 supplied no arguments to the Time class constructor. Suppose you would like to create Time objects with any legitimate hour, minute and/or second values. Class Time of Fig. 9.3 includes five overloaded constructors to provide several ways to initialize Time objects. Each constructor calls method SetTime of the Time object, which uses the Set accessors of properties Hour, Minute and Second to ensure that the object begins in a consistent state by setting out-of-range hour, minute and second values to 12, 0 and 0, respectively. The compiler invokes the appropriate constructor by matching the number, types and order of the arguments specified in the constructor call with the number, types and order of the parameters specified in each constructor method declaration.

Figure 9.3. Overloaded constructors and Optional arguments.

  1   ' Fig. 9.3: Time.vb  2   ' Represents time and contains overloaded constructors.  3   Class Time  4      ' declare Integer instance variables for the hour, minute and second  5      Private hourValue As Integer ' 0 - 23  6      Private minuteValue As Integer ' 0 - 59  7      Private secondValue As Integer ' 0 - 59  8  9      ' constructor initializes hour to 12, minute to 0 and second to 0 10      ' to ensure that each Time object starts in a consistent state 11      Public Sub New () ' parameterless constructor 12         SetTime(12) ' initialize hour to noon; minute and second to 0 13      End Sub ' New 14 15      ' Time constructor: hour supplied; 16      ' minute and second default to 0 17      Public Sub New(ByVal hh As Integer) 18         SetTime(hh) ' call SetTime with one argument 19      End Sub ' New 20 21      ' Time constructor: hour and minute supplied; 22      ' second defaults to 0 23      Public Sub New (ByVal hh As Integer, ByVal mm As Integer) 24         SetTime(hh, mm) ' call SetTime with two arguments 25      End Sub ' New 26 27      ' Time constructor: hour, minute and second supplied 28      Public Sub New (ByVal hh As Integer, _       29         ByVal mm As Integer, ByValss As Integer) 30         SetTime(hh, mm, ss) ' call SetTime with three arguments 31      End Sub ' New 32 33      ' Time constructor: another Time object supplied 34      Public Sub New(ByVal tt As Time) 35         SetTime(tt.Hour, tt.Minute, tt.Second) 36      End Sub ' New 37 38      ' set a new time value using universal time, check validity of the 39      ' data, set invalid hour to 12, set invalid minute/second to zero 40      Public Sub SetTime(Optional ByVal hh As Integer =12, _                  41         Optional ByVal mm As Integer = 0, Optional ByVal, ss As Integer = 0) 42         Hour = hh ' set hourValue using the Hour property 43         Minute = mm ' set minuteValue using the Minute property 44         Second = ss ' set secondValue using the Second property 45      End Sub ' SetTime 46 47      ' property Hour 48      Public Property Hour() As Integer 49         Get ' return hourValue 50            Return hourValue 51         End Get 52 53        Set(ByVal value As Integer) ' set hourValue 54           If (value >= 0 AndAlso value < 24) Then ' in range 0-23 55              hourValue = value ' value is valid 56           Else ' value is invalid 57              hourValue = 12 ' set to default of noon 58          End If 59       End Set 60      End Property ' Hour 61 62      ' property Minute 63      Public Property Minute() As Integer 64         Get ' return minuteValue 65            Return minuteValue 66         End Get 67 68         Set(ByVal value As Integer) ' set minuteValue 69            If (value >= 0 AndAlso value < 60) Then ' in range 0-59 70               minuteValue = value ' value is valid 71            Else ' value is invalid 72               minuteValue = 0 ' set to default of 0 73            End If 74         End Set 75      End Property ' Minute 76 77      ' property Second 78      Public Property Second() As Integer 79         Get ' return secondValue 80            Return secondValue 81         End Get 82 83         Set(ByVal value As Integer) ' set secondValue 84            If (value >= 0 AndAlso value < 60) Then ' in range 0-59 85               secondValue = value ' value is valid 86            Else ' value is invalid 87               secondValue = 0 ' set to default of 0 88            End If 89         End Set 90      End Property ' Second 91 92      ' convert Time to a String in universal-time (24-hour clock) format 93      Public Function ToUniversalString() As String 94         Returnx String.Format( "{0}:{1:D2}:{2:D2}", Hour, Minute, Second) 95      End Function ' ToUniversalString 96 97      ' convert Time to a String in standard-time (12-hour clock) format 98      Public Overrides Function ToString() As String 99         Dim suffix As String ' AM or PM suffix 100        Dim standardHour As Integer ' a standard hour in the range 1-12 101 102        ' determine whether the 12-hour clock suffix should be AM or PM 103        If Hour < 12 Then 104           suffix = " AM"' note space preceding AM 105        Else 106           suffix = " PM"' note space preceding PM 107        End If 108 109        ' convert hour from universal-time format to standard-time format 110        If (Hour = 12 OrElse Hour = 0) Then 111           standardHour = 12 112        Else 113           standardHour = Hour Mod 12 ' 1 through 11, AM or PM 114        End If 115 116        Return String.Format( "{0}:{1:D2}:{2:D2}", standardHour, Minute, _ 117           Second) & suffix 118     End Function ' ToString 119  End Class ' Time 

Class Time's Constructors

Because most of the code in class Time is identical to that in Fig. 9.1, this section concentrates only on the overloaded constructors. Lines 1113 define the parameterless constructor that calls SetTime (line 12), initializing the time to noon. Lines 1719 define a Time constructor with a single Integer parameter, representing the hour. Lines 2325 define a Time constructor with two Integer parameters, representing the hour and minute. Lines 2831 define a Time constructor with three Integer parameters representing the hour, minute and second. Lines 3436 define a Time constructor that receives a reference to another Time object. When this last constructorsometimes called a copy constructoris called, the values from the Time argument are copied to initialize the new object's hour-Value, minuteValue and secondValue. Class Time declares these values as Private (lines 57), but the new Time object's constructor obtains these values via the Public properties of its Time parameter by using the expressions tt.Hour, tt.Minute and tt.Second. In fact, line 35 could have accessed the argument Time object's instance variables directly with the expressions tt.hourValue, tt.minuteValue and tt.secondValue.

Software Engineering Observation 9.2

When one object of a class has a reference to another object of the same class, the first object can access all of the second object's data, methods and properties (including those that are Private).


Although the parameter to the constructor in lines 3436 is passed by value, this does not make a copy of the Time object that is passed as the constructor's argument. Rather, it makes a copy of the reference to the Time object passed as the argument.

Software Engineering Observation 9.3

Visual Basic classes are reference types, so all Visual Basic objects are passed to methods by reference.


Note that each constructor receives a different number and/or different types of parameters. Also, recall that if a method has one or more Optional parameters, the caller has the option of passing a value for each parameter. Method SetTime declares three Optional parametershh, mm and ss (lines 4041). Lines 12 and 18 call method SetTime with one argument, which indicates that the default values for the Optional minuteValue and secondValue parameters should be used. Line 24 calls method SetTime with two arguments, which indicates that the default value for the Optional parameter secondValue is used. Lines 30 and 35 call method SetTime with all three arguments, so that no default values are used.

Common Programming Error 9.3

A constructor can call other class methods that use instance variables not yet initialized. Using instance variables before they have been initialized can lead to logic errors.


Using Class Time's Overloaded Constructors

Figure 9.4 (TimeTest.vb) demonstrates class Time's overloaded constructors. Lines 611 create six Time objects that invoke various constructors of the class. Line 6 invokes the parameterless constructor by placing an empty set of parentheses after the class name. Lines 711 demonstrate passing arguments to the Time constructors. Line 7 invokes the constructor at lines 1719 of Fig. 9.3. Line 8 invokes the constructor at lines 2325 of Fig. 9.3. Lines 910 invoke the constructor at lines 2831 of Fig. 9.3. Line 11 invokes the constructor at lines 3436 of Fig. 9.3.

Figure 9.4. Overloading Constructors.

  1  ' Fig. 9.4: TimeTest.vb  2  ' Overloading constructors.  3  Module TimeTest  4     Sub Main()  5        ' use overloaded constructors                                    6        Dim time1 As New Time() ' constructor with zero parameters       7        Dim time2 As New Time(2) ' constructor with one parameter        8        Dim time3 As New Time(21, 34) ' constructor with two parameters  9        Dim time4 As New Time(12, 25, 42) ' three valid arguments       10        Dim time5 As New Time(27, 74, 99) ' three invalid arguments     11        Dim time6 As New Time(time4) ' copy another Time object         12 13        ' invoke time1 methods 14        Console.WriteLine("Constructed with: " & vbCrLf & _ 15           "time1: all arguments defaulted" & vbCrLf & vbTab & _ 16           time1.ToUniversalString() & vbCrLf & vbTab & _ 17           time1.ToString()) 18        ' invoke time2 methods 19        Console.WriteLine( _ 20           "time2: hour specified; minute and second defaulted" & _ 21           vbCrLf & vbTab & time2.ToUniversalString() & _ 22           vbCrLf & vbTab & time2.ToString()) 23        ' invoke time3 methods 24        Console.WriteLine( _ 25           "time3: hour and minute specified; second defaulted" & _ 26           vbCrLf & vbTab & time3.ToUniversalString() & _ 27           vbCrLf & vbTab & time3.ToString()) 28        ' invoke time4 methods 29        Console.WriteLine("time4: hour, minute and second specified" & _ 30           vbCrLf & vbTab & time4.ToUniversalString() & _ 31           vbCrLf & vbTab & time4.ToString()) 32        ' invoke time5 methods 33        Console.WriteLine( _ 34           "time5: invalid hour, minute and second specified" & _ 35           vbCrLf & vbTab & time5.ToUniversalString() & _ 36           vbCrLf & vbTab & time5.ToString()) 37        ' invoke time6 methods 38        Console.WriteLine("time6: Time object copied from time4" & _ 39           vbCrLf & vbTab & time6.ToUniversalString() & _ 40           vbCrLf & vbTab & time6.ToString()) 41     End Sub ' Main 42  End Module ' TimeTest 

Constructed with: time1: all arguments defaulted         12:00:00         12:00:00 PM time2: hour specified; minute and second defaulted         2:00:00         2:00:00 AM time3: hour and minute specified; second defaulted         21:34:00         9:34:00 PM time4: hour, minute and second specified         12:25:42         12:25:42 PM time5: invalid hour, minute and second specified         12:00:00         12:00:00 PM time6: Time object copied from time4         12:25:42         12:25:42 PM 



Each Time constructor can be written to include a copy of the appropriate statements from method SetTime. This might be slightly more efficient, because it eliminates the extra SetTime call. However, consider what would happen if you change the representation of the time from three Integer values (requiring 12 bytes of memory) to a single Integer value representing the total number of elapsed seconds since midnight (requiring only 4 bytes of memory). Placing identical code in the Time constructors and method Set-Time makes such a change in the class declaration more difficult. If the implementation of SetTime changes, the implementation of all the Time constructors would need to change accordingly. If, on the other hand, the Time constructors call method SetTime directly, any changes to the implementation of SetTime must be made only once, thus reducing the likelihood of a programming error when altering the implementation.

Software Engineering Observation 9.4

If a method of a class provides functionality required by a constructor (or other method) of the class, call that method from the constructor (or other method). This simplifies the maintenance of the code and reduces the likelihood of code errors.




Visual BasicR 2005 for Programmers. DeitelR Developer Series
Visual Basic 2005 for Programmers (2nd Edition)
ISBN: 013225140X
EAN: 2147483647
Year: 2004
Pages: 435

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