The source program of Listing 10.13 shown later utilizes an array of elevators (line 35) to effectively control a collection of elevators. It is used to demonstrate the syntax and mechanics involved when array elements hold references to objects. Recall the elevator simulation example from Chapter 5. It defined an Elevator similar to that found in lines 3 29 of Listing 10.13, but only employed one of this kind. The Main() method (lines 33 54) in contrast manages 10 elevators.
To better focus on the important issues surrounding arrays of objects, the program has omitted some of the aspects included in the example of Chapter 5. There are, for example, no Person objects here; instead, the elevators are manipulated directly from the Main() method, where each Elevator object is accessed through the array of elevators.
Lines 3 29 define a bare bones Elevator class. It can keep track of its current floor position (through currentFloorNumber declared in line 5) and its total number of floors traveled (floorsTraveled of line 6). Both instance variables are initialized to zero by the constructor defined in lines 8 12. A constructor is, as you might recollect, automatically called and executed during the process of creating a new object, and is a handy mechanism to perform various initializations.
An Elevator object can be moved to a new floor (MoveToFloor lines 14 18), return the total number of floors traveled (GetFloorsTraveled lines 20 23), and can return its current floor location (lines 25 28). We are now able to create and manage a large group of Elevator objects. This can effectively be done by keeping their references neatly ordered and indexed inside an array of base type Elevator. Our humble aim here is merely to control 10 Elevator objects inside the Main() method. To declare the elevator array, we exchange the name of the primitive types we have utilized so far with the name of our custom designed type Elevator. Thus,
Elevator [] elevators
of line 35 specifies elevators to be an array variable of base type Elevator. So far, elevators only references null, as illustrated in Figure 10.13, so it needs to be assigned a reference to an array object of base type Elevator and length 10.
As usual, this can be done with the new keyword. For example, after line 35
Elevator [] elevators = new Elevator[10];
elevators is referencing an array object with ten array elements of type reference-to-Elevator-object. However, because none of them have yet been assigned a reference to a particular Elevator object, they are all null, as illustrated in Figure 10.14.
For each array element in elevators, we need to create an Elevator object and assign its reference to this array element (lines 36 39). As the for loop increments i from 0 to 9, each elevators element is assigned a reference to a freshly created Elevator object through the following loop body found in line 38:
elevators[i] = new Elevator();
Each array element is now referencing an Elevator object, as illustrated in Figure 10.15.
Finally, the 10 elevators are ready to be accessed and used.
To identify a particular Elevator object, we need to specify the relevant index in square brackets after the array variable name. The first Elevator object can, for example, be referenced by writing the following:
elevators[0]
To call a method of the referenced object, we simply need to apply the dot operator followed by the name of the method, as in line 41:
elevators[0].MoveToFloor(10);
which calls the MoveToFloor method of the first Elevator object in elevators and passes along the argument 10.
Lines 41 44 "moves" the first and the fifth elevator a couple of times each. We could have involved elevators in a much more elaborate set of movements involving all 10 elevators and sophisticated movement-generating algorithms, but this would sidetrack us from the issues discussed here.
Lines 46 53 calls the GetFloorsTraveled and GetCurrentFloorNumber methods of each Elevator object and provides an overview of the current state of each object. As you can see from the sample output, as expected, only the first and the fifth elevator are shown to have been moved.
01: using System; 02: 03: class Elevator 04: { 05: private int currentFloorNumber; 06: private int floorsTraveled; 07: 08: public Elevator() 09: { 10: currentFloorNumber = 0; 11: floorsTraveled = 0; 12: } 13: 14: public void MoveToFloor(int toFloorNumber) 15: { 16: floorsTraveled += Math.Abs(currentFloorNumber - toFloorNumber); 17: currentFloorNumber = toFloorNumber; 18: } 19: 20: public int GetFloorsTraveled() 21: { 22: return floorsTraveled; 23: } 24: 25: public int GetCurrentFloorNumber() 26: { 27: return currentFloorNumber; 28: } 29: } 30: 31: class ElevatorArray 32: { 33: public static void Main() 34: { 35: Elevator [] elevators = new Elevator[10]; 36: for (int i = 0; i < elevators.Length; i++) 37: { 38: elevators[i] = new Elevator(); 39: } 40: 41: elevators[0].MoveToFloor(10); 42: elevators[4].MoveToFloor(20); 43: elevators[0].MoveToFloor(5); 44: elevators[4].MoveToFloor(7); 45: 46: Console.WriteLine("Total floors traveled and current location for eachelevator\n"); 47: Console.WriteLine(" Floors traveled Current location"); 48: for (int i = 0; i < elevators.Length; i++) 49: { 50: Console.WriteLine("Elevator { 0,2} : { 1,4} { 2,4} ", 51: (i + 1), elevators[i].GetFloorsTraveled(), 52: elevators[i].GetCurrentFloorNumber()); 53: } 54: } 55: }
Total floors traveled and current location for each elevator
Floors traveled Current location Elevator 1: 15 5 Elevator 2: 0 0 Elevator 3: 0 0 Elevator 4: 0 0 Elevator 5: 33 7 Elevator 6: 0 0 Elevator 7: 0 0 Elevator 8: 0 0 Elevator 9: 0 0 Elevator 10: 0 0