Section 9.7. Composition


9.7. Composition

A class can have references to objects of other classes as members. Such a capability is called composition and is sometimes referred to as a has-a relationship. For example, an object of class AlarmClock needs to know the current time and the time when it is supposed to sound its alarm, so it is reasonable to include two references to Time objects as members of the AlarmClock object.

Software Engineering Observation 9.5

One form of software reuse is composition, in which a class has as members references to objects of other classes.


Our example of composition contains two classesDay (Fig. 9.5) and Employee (Fig. 9.6)and module CompositionTest (Fig. 9.7) to demonstrate them. Class Day (Fig. 9.5) encapsulates information relating to a specific date. Lines 46 declare Integers monthValue, dayValue and yearValue. Lines 1015 declare the constructor, which receives as parameters values for the month, day and year, then assigns these values to the class's properties to ensure that the parameter values are valid.

Figure 9.5. Day class encapsulates day, month and year information.

  1  ' Fig. 9.5: Day.vb  2  ' Encapsulates month, day and year.  3  Class Day  4     Private monthValue As Integer ' 1-12                      5     Private dayValue As Integer ' 1-31 based on month         6     Private yearValue As Integer ' any year (could validate)  7  8     ' constructor confirms proper value for month, then calls  9     ' method CheckDay to confirm proper value for day 10     Public Sub New(ByVal mm As Integer, _             11        ByVal dd As Integer, ByVal yy As Integer)       12        Month = mm 13        Day = dd 14        Year = yy 15     End Sub ' New 16 17     ' property Month 18     Public Property Month() As Integer 19        Get 20           Return monthValue 21        End Get 22 23        Set(ByVal mm As Integer) 24           ' ensure month value is valid (in the range 1-12) 25           If (mm > 0 AndAlso mm <= 12) Then 26              monthValue = mm 27           Else 28              monthValue = 1 ' to ensure consistent state 29 30              ' inform user of error 31              Console.WriteLine("Invalid month (" & mm & _ 32                 ") set to 1.") 33           End If 34        End Set 35     End Property ' Month 36 37     ' property Day 38     Public Property Day() As Integer 39        Get 40           Return dayValue 41        End Get 42 43        Set(ByVal dd As Integer) 44           dayValue = CheckDay(dd) ' validate dayPassed 45        End Set 46     End Property ' Day 47 48     ' property Year 49     Public Property Year() As Integer 50        Get 51           Return yearValue 52        End Get 53 54        Set(ByVal yy As Integer) 55           yearValue = yy 56        End Set 57     End Property ' Year 58 59     ' confirm proper day value based on month and year 60     Private Function CheckDay(ByVal testDayValue As Integer) As Integer 61        Dim daysPerMonth() As Integer = _ 62           {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 63 64        ' validate day 65        If (testDayValue > 0 AndAlso _ 66           testDayValue <= daysPerMonth(Month)) Then 67           Return testDayValue 68        End If 69 70        ' check for leap year in February 71        If (Month = 2 AndAlso testDayValue = 29 AndAlso _ 72           ((Year Mod 400 = 0) OrElse _ 73           (Year Mod 4 = 0 AndAlso Year Mod 100 <> 0))) Then 74           Return testDayValue 75        End If 76 77        ' inform user of error 78        Console.WriteLine("Invalid day (" & testDayValue & ") set to 1. ") 79        Return 1 ' leave object in consistent state 80     End Function ' CheckDay 81 82     ' create string containing month/day/year format 83     Public Overrides Function ToString() As String 84        Return (Month & "/" & Day & "/" & Year) 85     End Function ' ToString 86  End Class ' Day 

Figure 9.6. Employee class encapsulates employee name, birthday and hire date.

  1  ' Fig. 9.6: Employee.vb  2  ' Represent employee name, birthday and hire date.  3  Class Employee  4     Private firstName As String  5     Private lastName As String  6     Private birthDate As Day ' member object reference  7     Private hireDate As Day ' member object reference   8  9     ' Employee constructor 10     Public Sub New(ByVal first As String, ByVal last As String, _ 11        ByVal birthMonth As Integer, ByVal birthDay As Integer, _ 12        ByVal birthYear As Integer, ByVal hireMonth As Integer, _ 13        ByVal hireDay As Integer, ByVal hireYear As Integer) 14 15        firstName = first 16        lastName = last 17 18        ' create Day instance for employee birthday          19        birthDate = New Day(birthMonth, birthDay, birthYear) 20 21        ' create Day instance for employee hire date     22        hireDate = New Day(hireMonth, hireDay, hireYear) 23     End Sub ' New 24 25        ' return employee information as String 26        Public Overrides Function ToString() As String 27           Return (lastName & ", " & firstName & " Hired:" _ 28              & hireDate.ToString() & "Birthday:" & birthDate.ToString()) 29        End Function ' ToString 30     End Class ' Employee 

Figure 9.7. Composition demonstration.

 1  ' Fig. 9.7: CompositionTest.vb 2  ' Demonstrate an object with member object reference. 3  Module CompositionTest 4     Sub Main() 5        Dim employee As New Employee( _ 6           "Bob", "Blue", 7, 24, 1949, 3, 12, 1988) 7        Console.WriteLine(employee.ToString()) 8     End Sub ' Main 9  End Module ' CompositionTest 

Blue, Bob Hired: 3/12/1988 Birthday: 7/24/1949



The Set accessor (lines 2334) of property Month ensures that the month value is in the range 112. The Set accessor (lines 4345) of property Day invokes utility function CheckDay to validate the day value. The Year property does not perform the validation of the year value. We assume that the Year is a valid four-digit year, such as 2005; however, we could have validated the year as well.

Function CheckDay (lines 6080) validates whether the day is correct based on the current Month and Year. Lines 6568 determine whether the day is a valid day for the particular month. If not, lines 7175 determine whether the Month is February, the day is 29 and the Year is a leap year. A year is a leap year if it is divisible by 400 (tested at line 72), or if it is divisible by 4 and not divisible by 100 (tested at line 73). If lines 7175 do not return a correct value for day, line 79 returns 1 to maintain the date in a consistent state.

Using Class Day in Class Employee

Class Employee (Fig. 9.6) holds information relating to an employee's birthday and hire date using instance variables firstName, lastName, birthDate and hireDate (lines 47). Members birthDate and hireDate are references to Day objects, each of which contains instance variables month, day and year. In this example, class Employee is composed of two references to Day objects. The Employee constructor (lines 1023) takes eight arguments (first, last, birthMonth, birthDay, birthYear, hireMonth, hireDay and hireYear). Line 19 passes arguments birthMonth, birthDay and birthYear to the Day constructor to create the birthDate object. Similarly, line 22 passes arguments hireMonth, hireDay and hireYear to the Day constructor to create the hireDate object.

Testing Class Employee

Module CompositionTest (Fig. 9.7) contains Main, which tests the classes in Figs. 9.59.6. Lines 56 instantiate an Employee object ("Bob Blue" with birthday 7/24/1949 and hire date 3/12/1988), and line 7 displays the Employee information to the user.



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