11.2. Arrays of Objects; Events; Containment
Arrays of ObjectsThe elements of an array can have any data typeincluding a user-defined object. The program in Example 1 uses an array of type Student. Example 1. |
In the following program, which uses the same form design as Example 1 of the previous section, the user enters four pieces of data about a student into text boxes. When the Enter Information button is pressed, the data are used to create and initialize an appropriate object and the object is added to an array. When the Display Grades button is pressed, the name, Social Security number, and semester grade for each student in the array are displayed in the list box. Public Class frmGrades Dim students(50) As Student Dim lastStudentAdded As Integer = -1 'Position in array of student 'most recently added Private Sub btnEnter_Click(...) Handles btnEnter.Click 'Create an instance of student. 'Read the values stored in the text boxes. Dim pupil As New Student() pupil.Name = txtName.Text pupil.SocSecNum = mtxtSSN.Text pupil.MidGrade = CDbl(txtMidterm.Text) pupil.Final = CDbl(txtFinal.Text) 'Add the student to the array lastStudentAdded += 1 students(lastStudentAdded) = pupil 'Clear text boxes txtName.Clear() mtxtSSN.Clear() txtMidterm.Clear() txtFinal.Clear() lstGrades.Items.Add("Student Recorded.") End Sub Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim fmtStr As String = "{0,-20}{1,-15}{2,-1}" lstGrades.Items.Clear() lstGrades.Items.Add(String.Format(fmtStr, "Student Name", _ "SSN", "Grade")) [Run, type in data for Al Adams, press the Enter Information button, repeat the process for Brittany Brown and Carol Cole, press the Display Grades button, and then enter data for Daniel Doyle.]
|
In the previous section, we drew a parallel between objects and controls and showed how to define properties and methods for classes. In addition to the predefined event New for classes, other events can be defined by the programmer to communicate changes of properties, errors, and the progress of lengthy operations. Such events are called user-defined events. The statement for triggering an event is located in the class block, and the event is dealt with in the form's code. Suppose that the event is named UserDefinedEvent and has the parameters par1, par2, and so on. In the class block, the statement
Public Event UserDefinedEvent(ByVal par1 As DataType1, _ ByVal par2 As DataType2, ...)
should be placed in the Declarations section, and the statement
RaiseEvent UserDefinedEvent(arg1, arg2, ...)
should be placed at the locations in the class block code at which the event should be triggered. In the form's code, an instance of the class, call it object1, must be declared with a statement of the type
Dim WithEvents object1 As ClassName
or the type
Dim WithEvents object1 As New ClassName
in order to be able to respond to the event. That is, the keyword WithEvents must be inserted into the declaration. The header of an event procedure for object1 will be
Private Sub object1_UserDefinedEvent(par1, par2, ...) _ Handles object1.UserDefinedEvent
Consider the circle class defined in Example 3 of Section 11.1. In the following program, we add a user-defined event that is triggered whenever the location of a circle changes. The event has parameters to pass the location and diameter of the circle. The form's code uses the event to determine if part (or all) of the drawn circle will fall outside the picture box. If so, the event procedure displays the message "Circle Off Screen" in a text box. Let's call the event PositionChanged.
Public Class frmCircle Dim WithEvents round As New Circle() Private Sub btnMove_Click(...) Handles btnMove.Click round.Move(20) End Sub Private Sub btnQuit_Click(...) Handles btnQuit.Click End End Sub [Run, and press the "Move and Show Circle" button eleven times.]
|
Note: As the last circle appears, the words "Circle Off Screen" are displayed in the text box.
We say that class A contains class B when a member variable of class A makes use of an object of type class B. In Example 3, the class DeckOfCards contains the class Card.
The following program deals a five-card poker hand. The program has a deck-of-cards object containing an array of 52 card objects. The card object has two properties, Denomination and Suit, and one method, IdentifyCard. The IdentifyCard method returns a string such as "Ace of Spades." In the DeckOfCards object, the New event procedure assigns denominations and suits to the 52 cards. The method ReadCard(n) returns the string identifying the nth card of the deck. The method ShuffleDeck uses the Random class to mix up the cards while making 2000 passes through the deck. The event Shuffling(n As Integer, nMax As Integer) is triggered during each shuffling pass through the deck, and its parameters communicate the number of the pass and the total number of passes, so that the program that uses it can keep track of the progress.
Public Class frmPoker Dim WithEvents cards As New DeckOfCards() Private Sub btnShuffle_Click(...) Handles btnShuffle.Click cards.ShuffleDeck End Sub Private Sub btnDeal_Click(...) Handles btnDeal.Click Dim str As String lstHand.Items.Clear() For i As Integer = 0 To 4 str = cards.ReadCard(i) lstHand.Items.Add(str) Next End Sub Private Sub Quit_Click(...) Handles Quit.Click End End Sub Private Sub cards_Shuffling(ByVal n As Integer, _ ByVal nMax As Integer) Handles cards.Shuffling 'n is the number of the specific pass through the deck (1, 2, 3...). 'nMax is the total number of passes when the deck is shuffled. lstHand.Items.Clear() lstHand.Items.Add("Shuffling Pass: " & n & " out of " & nMax) For i As Integer = 1 To 1000000 'Slow down the shuffle. Next lstHand.Update() 'Refresh contents of list box End Sub End Class [Run, click on the Shuffle button, and click on the Deal button after the shuffling is complete.]
|
Consider the program in Example 1, and suppose that mtxtSSN is an ordinary text box.
1. | Alter the Set SocSecNum property procedure to raise the event ImproperSSN when the Social Security number does not have 11 characters. The event should pass the length of the Social Security number and the student's name to the form's code. |
2. | What statement must be placed in the Declarations section of the class block? |
3. | Write an event procedure for the event ImproperSSN. |
4. | What statement in the form's code must be altered? |
1. | In Example 1, modify the event procedure btnDisplay_Click so that only the students who receive a grade of A are displayed. The file STATES.TXT provides data on the 50 states. (This file is used in Exercises 2 through 5.) Each record contains five pieces of information about a single state: name, abbreviation, date it entered the union, land area (in square miles), and population in the year 2000. The records are ordered by the date of entry into the union. The first five lines of the file are Delaware DE Dec. 1787 1954 759000 |
2. | Create (a) a class State with five properties to hold the information about a single state and (b) a method that calculates the density (people per square mile) of the state. |
3. | Write a program that requests a state's name in an input dialog box and displays the state's abbreviation, density, and date of entrance into the union. The program should use an array of State objects. |
4. | Write a program that displays the names of the states and their densities in a list box ordered by density. The program should use an array of State objects. |
5. | Write a program that reads the data from the file into an array of State objects and raises an event whenever the population of a state exceeds ten million. States with a large population should have their names and populations displayed in a list box by the corresponding event procedure. Hint: Create a class called UnitedStates that contains the array and defines a method Add that adds a new state to the array. The Add method should raise the event. |
6. | Consider the class Square from Exercise 19 of Section 11.1 Add the event IllegalNumber that is raised when any of the properties is set to a negative number. Show the new class block and write an event procedure for the event that displays an error message. |
7. | Consider the CashRegister class in Exercise 25 of Section 11.1. Add the event AttemptToOverdraw that is raised when the user tries to subtract more money than is in the cash register. |
8. | Consider the class PairOfDice discussed in Exercise 21 of Section 11.1. Add the event SnakeEyes that is raised whenever two ones appear during a roll of the dice. Write a program that uses the event. |
9. | Consider the Fraction class in Exercise 29 of Section 11.1. Add the event ZeroDenominator, that is triggered whenever a denominator is set to 0. Write a program that uses the event. |
10. | Write a program for the fraction calculator shown in Figure 11.3. After the numerators and denominators of the two fractions to the left of the equals sign are placed in the four text boxes, one of four operations buttons should be pressed. The result appears to the right of the equals sign. The program should use a Calculator class, which contains three members of the type Fraction discussed in Exercise 29 of Section 11.1. Note: In Figure 11.3, the fraction bars are very short list boxes. Figure 11.3. Sample Output for Exercise 10.
|
11. | Write a program that takes orders at a fast food restaurant. See Figure 11.4. The restaurant has two menus, a regular menu and a kids menu. An item is ordered by highlighting it in one of the list boxes and then pushing the >> or << button to place it in the order list box in the center of the form. As each item is ordered, a running total is displayed in the text box at the lower right part of the form. The program should use a Choices class, which contains a Food class. (The contents of each of the three list boxes should be treated as Choices objects.) Each Food object should hold the name and price of a single food item. Each Choices object should have a ChoiceChanged event that can be used by the form code to update the cost of the order. Figure 11.4. Sample Output for Exercise 11. |
12. | Write a program for a simple game in which each of two players rolls a pair of dice. The person with the highest tally wins. See Figure 11.5. The program should use a Game class (HighRoller) having two member variables of the type PairOfDice discussed in Exercise 21 of Section 11.1. Figure 11.5. Sample output for Exercise 12.
|
13. | Write a program to produce an employee's weekly paycheck receipt. The receipt should contain the employee's name, amount earned for the week, total amount earned for the year, FICA tax deduction, withholding tax deduction, and take-home amount. The program should use an Employee class and a Tax class. The Tax class must have properties for the amount earned for the week, the prior total amount earned for the year, the number of withholding exemptions, and marital status. It should have methods for computing FICA and withholding taxes. The Employee class should store the employee's name, number of withholding allowances, marital status, hours worked this week, hourly salary, and previous amount earned for the year. The Employee class should use the Tax class to calculate the taxes to be deducted. The formula for calculating the FICA tax is given in Exercise 28 of Section 11.1. To compute the withholding tax, multiply the number of withholding allowances by $61.54, subtract the product from the amount earned, and use Table 11.1 or Table 11.2. |
Adjusted Weekly Income | Income Tax Withheld |
---|---|
$0 to $51 | $0 |
Over $51 to $188 | 10% of amount over $51 |
Over $188 to $606 | $13.70 + 15% of amount over $188 |
Over $606 to $1,341 | $76.40 + 25% of amount over $606 |
Over $1,341 to $2,922 | $260.15 + 28% of amount over $1,341 |
Over $2,922 to $6,313 | $702.83 + 33% of amount over $2,922 |
Over $6,313 | $1,821.86 + 35% of amount over $6,313 |
Adjusted Weekly Income | Income Tax Withheld |
---|---|
$0 to $154 | $0 |
Over $154 to $435 | 10% of amount over $154 |
Over $435 to $1,273 | $28.10 + 15% of amount over $435 |
Over $1,273 to $2,322 | $153.80 + 25% of amount over $1,273 |
Over $2,322 to $3,646 | $416.05 + 28% of amount over $2,322 |
Over $3,646 to $6,409 | $786.77 + 33% of amount over $3,646 |
Over $6,409 | $1,698.56 + 35% of amount over $6,409 |
1. | Public Property SocSecNum() As String Get Return m_ssn End Get Set(ByVal value As String) If value.Length = 11 Then m_ssn = value Else RaiseEvent ImproperSSN(value.Length, m_name) End If End Set End Property |
2. | Public Event ImproperSSN(ByVal length As Integer, _ ByVal studentName As String) |
3. | Private Sub pupil_ImproperSSN(ByVal length As Integer, _ ByVal studentName As string) Handles pupil.ImproperSSN MsgBox("The social security number entered for " & _ studentName & " consisted of " & length & _ " characters. Reenter the data for " & studentName & ".") End Sub |
4. | The statement Dim pupil As New Student() must be changed to Dim WithEvents pupil As New Student() and moved to the Declaration section. |