Arrays As Instance Variables in Classes

   


The typical framework for a class definition seen so far in this book looks like the following:

 class AnyClass {       <Instance Variables>       <Methods>       <Others> } 

The instance variables we have declared in our classes have up till now, mostly consisted of primitive types, but they can also be objects, such as System.Array objects. The following example illustrates.

Consider a simulation involving a Building class. Somehow, we want it to be implemented so that it "contains" numerous Elevator and Floor objects, just like its real counterpart. The following definition of the Building class contains declarations of two instance variables, both of type System.Array, called elevators and floors, respectively, making this request possible:

 class Building {     private Elevator [] elevators;     private Floor [] floors;     <Other instance variables>     <Methods>     <Others> } 

We can now, from within one of the methods of the Building class, assign new array objects with a specified number of elevators and floors to these two array variables. If we wanted to create a building containing 10 elevators and 30 floors, we could instantiate a Building object and initialize elevators and floors with the following statements:

 elevators = new Elevator[10]; floors = new Floor[30]; 

Let's look at another example in more detail, this time involving banks and account balances.

So far, we have made extensive use of the accountBalances array to demonstrate several aspects of the array. The idea of a collection of account balances (represented by an array of values of a primitive type like decimal) as an instance variable in a Bank class is good (I hope) to demonstrate the syntax and semantics of arrays in a simple context. However, to tackle the complexities contained in software for a real world bank we need to make this approach more object-oriented. How can this be done? Rather than a list of account balances, a bank can be perceived to contain a collection of accounts. We can thus create an Account class written briefly as follows:

 class Account {       <Instance variable>       <Methods> } 

…and a Bank class with a collection of Account objects as in:

 class Bank {       private Account [] accounts;       <Other instance variables>       <Methods> } 

The following case study continues the story and shows you how to build a relatively simple bank simulation program by using an array of accounts as an instance variable in a Bank class.

Case Study: Bank Simulation Program

The final complete source code of this case study is provided in Listing 10.14, later in this case study, and will be referenced throughout the discussion.

Software specification:

The program written in this case study will simulate a bank holding several bank accounts. The accounts of the bank can be accessed and manipulated via a simple user interface provided from the console window. In particular, the user must, by giving simple commands, be able to

  • Initially specify the number of accounts managed by the bank

  • Deposit money into a specified account

  • Withdraw money from a specified account

  • Set the interest rate of a specific account

  • Add interest to all accounts

  • Print all account balances

  • Print total interest paid to each account

  • Print interest rate of each account

  • End the simulation

Software design:

Segregating each subsystem into objects (modules):

Two obvious classes can be identified Account (lines 3 51) and Bank (lines 53 144), along with the class BankSimulation (lines 146 205); it contains the Main() method that glues together the various parts of the program and responds to user input.

Identify the instance variables of the classes:

According to the software specification, an Account object must keep track of the following information:

  • Its balance

  • Its current interest rate

  • The total interest paid to it

Consequently, the Account class must contain the following instance variables (see lines 5 7):

 private decimal balance; private decimal currentInterestRate; private decimal totalInterestPaid; 

The Bank class contains a collection of accounts. All information relevant for the Bank can be found within the account objects. Consequently, the Bank class merely needs a single instance variable an array of accounts. The declaration looks like the following (see line 55):

 private Account [] accounts; 

The BankSimulation class merely needs one instance variable a Bank object (declared in line 148).

Identify the methods in each module:

  • Accountclass All instance variables should be initialized at the creation time of the object to which they belong. The constructor of lines 9 14 accomplishes this task. Recall that a constructor is a method with the same name as the class in which it resides. It is invoked during the creation of a new Account object. In our case, it initializes all instance variables to zero.

    All instance variables of Account are declared private to prevent any access from outside the object. As a consequence, we must define special methods, called accessor and mutator methods, to get and set the instance variables that must be retrieved and/or set directly. currentInterestRate requires two accessor methods, here called SetInterestRate (lines 16 19) and GetInterestRate (lines 21 24). balance is updated via the Deposit (lines 32 35) and Withdraw (lines 37 40) methods; however, the value must be returned via an accessor-method here called GetBalance (lines 42 45). totalInterestPaid is updated through the UpdateInterest method (lines 26 30) but must be returned with an accessor method, here called GetTotalInterestPaid (lines 47 50).

    Note

    graphics/common.gif

    In Chapter 14, "Class Anatomy Part III: Writing Intuitive Code," you will be introduced to properties that constitute a better way to access instance variables than accessor and mutator methods. For now, though, we can live happily without properties.


  • Bank class Whenever a new Bank object is created, we must create the Account objects it will manage, and assign their references to the array elements of accounts. This task could be performed by a standard method that is called after the creation of a Bank object. However, because this procedure must be performed for any new Bank object for it to be of any use, I decided to let a constructor perform the task (see lines 57 66). When a new Bank is created, as in line 154, the user will automatically be asked to enter the number of bank accounts controlled by the bank. Notice that the number of accounts once decided cannot be changed during the entire execution of the bank simulation.

    The newly created account objects residing inside accounts are now ready to be accessed. All the methods of the Bank class are devoted to updating or retrieving information from a single account or the entire collection of accounts and are, consequently, heavily dependent on the methods exposed by the Account class.

    The following methods work in a very similar manner in that they all ask the user to enter a specific account number and then permit the user to perform the requested action on the particular account.

    • Deposit (lines 68 79)

    • Withdraw (lines 81 92)

    • SetInterestRate (lines 94 103)

    In contrast, the subsequent four methods traverse through the entire collection of accounts to update a particular instance variable in each Account, or simply to access information for printing purposes:

    • PrintAllInterestRates (lines 105 113)

    • PrintAllBalances (lines 115 123)

    • PrintTotalInterestPaidAllAccounts (lines 125 133)

    • UpdateInterestAllAccounts (lines 135 143)

  • BankSimulation class The BankSimulation class provides a container for a Bank object and the Main() and PrintMenu methods. The latter evolves around a do-while loop combined with a switch statement to respond to user commands. Notice how relatively simple the Main() method is. All major tasks have been delegated to other methods either residing inside BankSimulation (the PrintMenu method) or inside the other objects of the simulation (Bank and Account).

Internal method design:

None of the methods in this program involve any elaborate algorithms, so I will just highlight a couple of smaller issues here in connection with the methods of the Bank class:

  1. accounts[0] contains a reference to an Account object. A method of this object can be called by applying the dot operator to accounts[0] as in the following:

     accounts[0].GetBalance() 

    which returns the balance of the first Account object.

  2. The user is led to believe that the first account is of index one (line 203). We must adjust for this when indexes entered or viewed by the user are used as indexes to access individual accounts. For example, in the Deposit method (lines 68 79) the user enters the account number of the account into which he or she wants to deposit money. The number is assigned to accountNumber, but will be one too big for our zero-based collection. The adjustments are performed in lines 76 and 78 by deducting one from accountNumber before it is passed as an index.

Listing 10.14 BankSimulation.cs
 01: using System;  02:  03: class Account  04: {  05:     private decimal balance;  06:     private decimal currentInterestRate;  07:     private decimal totalInterestPaid;  08:  09:     public Account()  10:     {  11:         balance = 0;  12:         currentInterestRate = 0;  13:         totalInterestPaid = 0;  14:     }  15:  16:     public void SetInterestRate(decimal newInterestRate)  17:     {  18:         currentInterestRate = newInterestRate;  19:     }  20:  21:     public decimal GetInterestRate()  22:     {  23:         return currentInterestRate;  24:     }  25:  26:     public void UpdateInterest()  27:     {  28:         totalInterestPaid += balance * currentInterestRate;  29:         balance += balance * currentInterestRate;  30:     }  31:  32:     public void Withdraw (decimal amount)  33:     {  34:         balance -= amount;  35:     }  36:  37:     public void Deposit (decimal amount)  38:     {  39:         balance += amount;  40:     }  41:  42:     public decimal GetBalance()  43:     {  44:         return balance;  45:     }  46:  47:     public decimal GetTotalInterestPaid()  48:     {  49:         return totalInterestPaid;  50:     }  51: }  52:  53: class Bank  54: {  55:     private Account [] accounts;  56:  57:     public Bank()  58:     {  59:         Console.WriteLine("Congratulations! You have created a new bank");  60:         Console.Write("Please enter number of accounts in bank: ");  61:         accounts = new Account[Convert.ToInt32(Console.ReadLine())];  62:         for (int i = 0; i < accounts.Length; i++)  63:         {  64:             accounts[i] = new Account();  65:         }  66:     }  67:   68:     public void Deposit()  69:     {  70:         int accountNumber;  71:         decimal amount;  72:         Console.Write("Deposit. Please enter account number: ");  73:         accountNumber = Convert.ToInt32(Console.ReadLine());  74:         Console.Write("Enter amount to deposit: ");  75:         amount = Convert.ToDecimal(Console.ReadLine());  76:         accounts[accountNumber - 1].Deposit(amount);  77:         Console.WriteLine("New balance of account { 0} : { 1:C} ",  78:             accountNumber, accounts[accountNumber - 1].GetBalance());  79:     }  80:  81:     public void Withdraw()  82:     {  83:         int accountNumber;  84:         decimal amount;  85:         Console.Write("Withdraw. Please enter account number: ");  86:         accountNumber = Convert.ToInt32(Console.ReadLine());  87:         Console.Write("Enter amount to withdraw: ");  88:         amount = Convert.ToDecimal(Console.ReadLine());  89:         accounts[accountNumber - 1].Withdraw(amount);  90:         Console.WriteLine("New balance of account { 0} : { 1:C} ",  91:             accountNumber, accounts[accountNumber - 1].GetBalance());  92:     }  93:  94:     public void SetInterestRate()  95:     {  96:         int accountNumber;  97:         decimal newInterestRate;  98:         Console.Write("Set interest rate. Please enter account number: ");  99:         accountNumber = Convert.ToInt32(Console.ReadLine()); 100:         Console.Write("Enter interest rate: "); 101:         newInterestRate = Convert.ToDecimal(Console.ReadLine()); 102:         accounts[accountNumber - 1].SetInterestRate(newInterestRate); 103:     } 104:  105:     public void PrintAllInterestRates() 106:     { 107:         Console.WriteLine("Interest rates for all accounts:"); 108:         for (int i = 0; i < accounts.Length; i++) 109:         { 110:             Console.WriteLine("Account { 0,-3} : { 1,-10} ", 111:                 (i + 1), accounts[i].GetInterestRate()); 112:         } 113:     } 114: 115:     public void PrintAllBalances() 116:     { 117:         Console.WriteLine("Account balances for all accounts:"); 118:         for (int i = 0; i < accounts.Length; i++) 119:         { 120:             Console.WriteLine("Account { 0,-3} : { 1,12:C} ", 121:                 (i + 1), accounts[i].GetBalance()); 122:         } 123:     } 124: 125:     public void PrintTotalInterestPaidAllAccounts() 126:     { 127:         Console.WriteLine("Total interest paid for each individual account"); 128:         for (int i = 0; i < accounts.Length; i++) 129:         { 130:             Console.WriteLine("Account { 0,-3} : { 1,12:C} ", 131:                 (i + 1), accounts[i].GetTotalInterestPaid()); 132:         } 133:     } 134: 135:     public void UpdateInterestAllAccounts() 136:     { 137:         for (int i = 0; i < accounts.Length; i++) 138:         { 139:             Console.WriteLine("Interest added to account number { 0,-3} : { 1,12:C}  graphics/ccc.gif", 140:                 (i + 1), accounts[i].GetBalance() * accounts[i].GetInterestRate()); 141:             accounts[i].UpdateInterest(); 142:         } 143:     } 144: } 145: 146: class BankSimulation 147: { 148:     private static Bank bigBucksBank; 149: 150:     public static void Main() 151:     { 152:         string command; 153: 154:         bigBucksBank = new Bank(); 155:         do 156:         { 157:             PrintMenu(); 158:             command = Console.ReadLine().ToUpper(); 159:             switch (command) 160:             { 161:                 case "D": 162:                     bigBucksBank.Deposit(); 163:                     break; 164:                 case "W": 165:                     bigBucksBank.Withdraw(); 166:                     break; 167:                 case "S": 168:                     bigBucksBank.SetInterestRate(); 169:                     break; 170:                 case "U": 171:                     bigBucksBank.UpdateInterestAllAccounts(); 172:                     break; 173:                 case "P": 174:                     bigBucksBank.PrintAllBalances(); 175:                     break; 176:                 case "T": 177:                     bigBucksBank.PrintTotalInterestPaidAllAccounts(); 178:                     break; 179:                 case "I": 180:                     bigBucksBank.PrintAllInterestRates(); 181:                     break; 182:                 case "E": 183:                     Console.WriteLine("Bye Bye!"); 184:                     break; 185:                 default: 186:                     Console.WriteLine("Invalid choice"); 187:                     break; 188:             } 189:         }  while (command != "E"); 190:     } 191: 192:     private static void PrintMenu() 193:     { 194:         Console.WriteLine("\nWhat would you like to do?\n" + 195:             "D)eposit\n" + 196:             "W)ithdraw\n" + 197:             "S)et interest rate\n" + 198:             "U)pdate all accounts for interest\n" + 199:             "P)rint all balances\n" + 200:             "T)otal interest paid printed for all accounts\n" + 201:             "I)nterest rates printed for all accounts\n" + 202:             "E)nd session\n" + 203:             "Note: First account has account number one"); 204:     } 205: } Congratulations! You have created a new bank Please enter number of accounts in bank: 7<enter> What would you like to do? D)eposit W)ithdraw S)et interest rate U)pdate all accounts for interest P)rint all balances T)otal interest paid printed for all accounts I)nterest rates printed for all accounts E)nd session Note: First account has account number one S<enter> Set interest rate. Please enter account number: 2<enter> Enter interest rate: 0.1<enter> What would you like to do? ... D<enter> Deposit. Please enter account number: 2<enter> Enter amount to deposit: 100000<enter> New balance of account 2: $100,000.00 What would you like to do? ... U<enter> Interest added to account number 1  :        $0.00 Interest added to account number 2  :   $10,000.00 Interest added to account number 3  :        $0.00 Interest added to account number 4  :        $0.00 Interest added to account number 5  :        $0.00 Interest added to account number 6  :        $0.00 Interest added to account number 7  :        $0.00 What would you like to do? ... P<enter> Account balances for all accounts: Account 1  :        $0.00 Account 2  :  $110,000.00 Account 3  :        $0.00 Account 4  :        $0.00 Account 5  :        $0.00 Account 6  :        $0.00 Account 7  :        $0.00 What would you like to do? ... E<enter> Bye Bye! 

Notes:

  • After every task has been accomplished, the 8 choices eposit, W)ithdraw, and so on) are printed onscreen. To save paper, these choices are only shown here once and then replaced by three dots.

  • The sample output does not demonstrate all of the functionalities found in the BankSimulation.cs program.


   


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

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