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.
|
Our example of composition contains three classesDate (Fig. 9.9), Employee (Fig. 9.10) and EmployeeTest (Fig. 9.11). Class Date (Fig. 9.9) declares instance variables month, day and year (lines 79) to represent a date. The constructor receives three int parameters. Line 15 implicitly invokes the set accessor of property Month (lines 4150) to validate the monthan out-of-range value is set to 1 to maintain a consistent state. Line 16 similarly uses property Year to set the yearbut notice that the set accessor of Year (lines 2831) assumes that the value for year is correct and does not validate it. Line 17 uses property Day (lines 5478), which validates and assigns the value for day based on the current month and year (by using properties Month and Year in turn to obtain the values of month and year). Note that the order of initialization is important because the set accessor of property Day validates the value for day based on the assumption that month and year are correct. Line 66 determines whether the day is correct based on the number of days in the particular Month. If the day is not correct, lines 6970 determine whether the Month is February, the day is 29 and the Year is a leap year. Otherwise, if the parameter value does not contain a correct value for day, line 75 sets day to 1 to maintain the Date in a consistent state. Note that line 18 in the constructor outputs the this reference as a string. Since this is a reference to the current Date object, the object's ToString method (lines 8184) is called implicitly to obtain the object's string representation.
Figure 9.9. Date class declaration.
1 // Fig. 9.9: Date.cs 2 // Date class declaration. 3 using System; 4 5 public class Date 6 { 7 private int month; // 1-12 8 private int day; // 1-31 based on month 9 private int year; // any year (could validate) 1011 // constructor: use property Month to confirm proper value for month; 12 // use property Day to confirm proper value for day 13 public Date( int theMonth, int theDay, int theYear ) 14 { 15 Month = theMonth; // validate month 16 Year = theYear; // could validate year 17 Day = theDay; // validate day 18 Console.WriteLine( "Date object constructor for date {0}", this ); 19 } // end Date constructor 20 21 // property that gets and sets the year 22 public int Year 23 { 24 get 25 { 26 return year; 27 } // end get 28 private set // make writing inaccessible outside the class 29 { 30 year = value; // could validate 31 } // end set 32 } // end property Year 33 34 // property that gets and sets the month 35 public int Month 36 { 37 get 38 { 39 return month; 40 } // end get 41 private set // make writing inaccessible outside the class 42 { 43 if ( value > 0 && value <= 12 ) // validate month 44 month = value; 45 else // month is invalid 46 { 47 Console.WriteLine( "Invalid month ({0}) set to 1.", value ); 48 month = 1; // maintain object in consistent state 49 } // end else 50 } // end set 51 } // end property Month 52 53 // property that gets and sets the day 54 public int Day 55 { 56 get 57 { 58 return day; 59 } // end get 60 private set // make writing inaccessible outside the class 61 { 62 int[] daysPerMonth = 63 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 64 65 // check if day in range for month 66 if ( value > 0 && value <= daysPerMonth[ Month ] ) 67 day = value; 68 // check for leap year 69 else if ( Month == 2 && value == 29 && 70 ( Year % 400 == 0 || ( Year % 4 == 0 && Year % 100 != 0 ) ) ) 71 day = value; 72 else 73 { 74 Console.WriteLine( "Invalid day ({0}) set to 1.", value ); 75 day = 1; // maintain object in consistent state 76 } // end else 77 } // end set 78 } // end property Day 79 80 // return a string of the form month/day/year 81 public override string ToString() 82 { 83 return string.Format( "{0}/{1}/{2}", Month, Day, Year ); 84 } // end method ToString 85 } // end class Date |
Figure 9.10. Employee class with references to other objects.
(This item is displayed on page 429 in the print version)
1 // Fig. 9.10: Employee.cs 2 // Employee class with references to other objects. 3 public class Employee 4 { 5 private string firstName; 6 private string lastName; 7 private Date birthDate; 8 private Date hireDate; 9 10 // constructor to initialize name, birth date and hire date 11 public Employee( string first, string last, 12 Date dateOfBirth, Date dateOfHire ) 13 { 14 firstName = first; 15 lastName = last; 16 birthDate = dateOfBirth; 17 hireDate = dateOfHire; 18 } // end Employee constructor 19 20 // convert Employee to string format 21 public override string ToString() 22 { 23 return string.Format( "{0}, {1} Hired: {2} Birthday: {3}", 24 lastName, firstName, hireDate, birthDate ); 25 } // end method ToString 26 } // end class Employee |
Figure 9.11. Composition demonstration.
(This item is displayed on page 430 in the print version)
1 // Fig. 9.11: EmployeeTest.cs 2 // Composition demonstration. 3 using System; 4 5 public class EmployeeTest 6 { 7 public static void Main( string[] args ) 8 { 9 Date birth = new Date( 7, 24, 1949 ); 10 Date hire = new Date( 3, 12, 1988 ); 11 Employee employee = new Employee( "Bob", "Blue", birth, hire ); 12 13 Console.WriteLine( employee ); 14 } // end Main 15 } // end class EmployeeTest
|
Class Employee (Fig. 9.10) has instance variables firstName, lastName, birthDate and hireDate. Members birthDate and hireDate (lines 78) are references to Date objects, demonstrating that a class can have as instance variables references to objects of other classes. The Employee constructor (lines 1118) takes four parametersfirst, last, dateOfBirth and dateOfHire. The objects referenced by parameters dateOfBirth and dateOfHire are assigned to the Employee object's birthDate and hireDate instance variables, respectively. Note that when class Employee's ToString method is called, it returns a string containing the string representations of the two Date objects. Each of these strings is obtained with an implicit call to the Date class's ToString method.
Class EmployeeTest (Fig. 9.11) creates two Date objects (lines 910) to represent an Employee's birthday and hire date, respectively. Line 11 creates an Employee and initializes its instance variables by passing to the constructor two strings (representing the Employee's first and last names) and two Date objects (representing the birthday and hire date). Line 13 implicitly invokes the Employee's ToString method to display the values of its instance variables and demonstrate that the object was initialized properly.
Preface
Index
Introduction to Computers, the Internet and Visual C#
Introduction to the Visual C# 2005 Express Edition IDE
Introduction to C# Applications
Introduction to Classes and Objects
Control Statements: Part 1
Control Statements: Part 2
Methods: A Deeper Look
Arrays
Classes and Objects: A Deeper Look
Object-Oriented Programming: Inheritance
Polymorphism, Interfaces & Operator Overloading
Exception Handling
Graphical User Interface Concepts: Part 1
Graphical User Interface Concepts: Part 2
Multithreading
Strings, Characters and Regular Expressions
Graphics and Multimedia
Files and Streams
Extensible Markup Language (XML)
Database, SQL and ADO.NET
ASP.NET 2.0, Web Forms and Web Controls
Web Services
Networking: Streams-Based Sockets and Datagrams
Searching and Sorting
Data Structures
Generics
Collections
Appendix A. Operator Precedence Chart
Appendix B. Number Systems
Appendix C. Using the Visual Studio 2005 Debugger
Appendix D. ASCII Character Set
Appendix E. Unicode®
Appendix F. Introduction to XHTML: Part 1
Appendix G. Introduction to XHTML: Part 2
Appendix H. HTML/XHTML Special Characters
Appendix I. HTML/XHTML Colors
Appendix J. ATM Case Study Code
Appendix K. UML 2: Additional Diagram Types
Appendix L. Simple Types
Index