### Application of upcasting: making a method more applicable

• Application of upcasting

• Upcasting is very useful to make a method more widely applicable:

 Upcasting allows a method that is written for the objects of the base class to be used for objects of any derived class of that base class

I will illustrate this with an example...

• Consider the Selection Sort Algorithm re-written to sort an array of BankAccount objects

(I have highlighted the changes made to the original program in red):

 ``` public class SortingTools { public static void SelectionSort(BankAccount[] a) { BankAccount help; // helper variable for 3-way exchange int i, j, min_j; // Array indices /* --------------------------------------------------- The selection sort algorithm --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i ++ ) { /* --------------------------------------------------- Find array element with min. value among a[i], a[i+1], ..., a[n-1] --------------------------------------------------- */ min_j = i; // Assume elem i (a[i]) is the minimum for ( j = i+1 ; j < a.length ; j++ ) { if ( a[j].getBalance() < a[min_j].getBalance() ) { min_j = j; // We found a smaller minimum, update min_j } } /* --------------------------------------------------- Swap a[i] and a[min_j] --------------------------------------------------- */ help = a[i]; a[i] = a[min_j]; a[min_j] = help; } } } ```

This selection sort method will sort BankAccount object by their balance values

• BTW: because the balance variable is private, we need to add a public method getBalance() that return the balance of a BankAccount object:

 ``` public class BankAccount { private int accNum; // Private access private String name; // -- accessible ONLY inside private double balance; // -- the class "BankAccount" /* ==================================================== Constructor 1: initialize all 3 instance variables ==================================================== */ public BankAccount(int a, String n, double amount) { accNum = a; name = n; balance = amount; } /* ============================================== getBalance(): return balance in BankAccount ============================================== */ public double getBalance() { return balance; } .... } ```

(Note: such a method should be written in the BankAccount class when we discuss classes.

I omitted it before for brevity....)

• Here is an example that show that the Selection Sort algorithm can sort an array of BankAccount objects:

 ``` public class SortBal1 { public static void main(String[] args) { BankAccount[] a = new BankAccount[4]; // 4 BankAccount ref. vars a[0] = new BankAccount(343, "John", 2000.0); a[1] = new BankAccount(123, "Mary", 1000.0); a[2] = new BankAccount(541, "Kate", 5000.0); a[3] = new BankAccount(224, "Adam", 3000.0); int i; /* --------------------------------------------------- Print array before sorting --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i++ ) { System.out.println( a[i] ); } SortingTools.SelectionSort(a); // Sort the BankAccount array "a" System.out.println( "Array after Selection Sort:"); /* --------------------------------------------------- Print array after sorting --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i++ ) { System.out.println( a[i] ); } } } ```

Output:

 ``` Account number: 343, Name: John, Balance: 2000.0 Account number: 123, Name: Mary, Balance: 1000.0 Account number: 541, Name: Kate, Balance: 5000.0 Account number: 224, Name: Adam, Balance: 3000.0 Array after Selection Sort: Account number: 123, Name: Mary, Balance: 1000.0 Account number: 343, Name: John, Balance: 2000.0 Account number: 224, Name: Adam, Balance: 3000.0 Account number: 541, Name: Kate, Balance: 5000.0 ```

• Example Program: (Demo above code)

How to run the program:

 Right click on links and save in a scratch directory To compile:   javac SortBal1.java To run:          java SortBal1

• Now, suppose we want to sort an array of CheckingAccount objects:

 ``` public class SortBal2 { public static void main(String[] args) { CheckingAccount[] a = new CheckingAccount[4]; a[0] = new CheckingAccount(343, "John", 2000.0); a[1] = new CheckingAccount(123, "Mary", 1000.0); a[2] = new CheckingAccount(541, "Kate", 5000.0); a[3] = new CheckingAccount(224, "Adam", 3000.0); int i; /* --------------------------------------------------- Print array before sorting --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i++ ) { System.out.println( a[i] ); } SortingTools.SelectionSort(a); // a is now of a different type !!! System.out.println( "Array after Selection Sort:"); /* --------------------------------------------------- Print array after sorting --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i++ ) { System.out.println( a[i] ); } } } ```

Facts:

• Because the type CheckingAccount is different than the type BankAccount, under normal circumstances, the Java compiler will report a uncompatible type error !!!

• Under normal circumstances, the method:

 ``` SelectionSort( BankAccount[] a ) { ... } ```

can only be used with parameter variables of the type BankAccount[].

• With the upcasting functionality:

 A CheckingAccount (derived class) reference can be casted to a BankAccount (base class) reference

the SelectionSort() method will also accept an array of CheckingAccount objects as parameter !!!

In fact:

 The SelectionSort() method will accept an array of any derived class object as parameter !!! So the SelectionSort() method is very flexible !!!

• Example Program: (Try it out for yourself !)

How to run the program:

 Right click on link and save in a scratch directory To compile:   javac SortBal2.java To run:          java SortBal2

• An experiment to show the usefulness of upcasting

• To prove to you that the SelectionSort algorithm will not work without upcasting, I have written a CheckingAccount class that does not inherit from BankAccount:

 ``` public class CheckingAccount // NO: extends BankAccount !!! { // NO relationship with BankAccount private int accNum; // Private access private String name; // -- accessible ONLY inside private double balance; // -- the class "BankAccount" /* ---------------------------------------------- Constructor: CheckingAccount(a, n, amount) ---------------------------------------------- */ public CheckingAccount(int a, String n, double amount) { accNum = a; name = n; balance = amount; } /* ============================================== getBalance(): return balance in BankAccount ============================================== */ public double getBalance() { return balance; } ... } ```

• If we compile the same SortBal2.java program:

 ``` public class SortBal2 { public static void main(String[] args) { CheckingAccount[] a = new CheckingAccount[4]; a[0] = new CheckingAccount(343, "John", 2000.0); a[1] = new CheckingAccount(123, "Mary", 1000.0); a[2] = new CheckingAccount(541, "Kate", 5000.0); a[3] = new CheckingAccount(224, "Adam", 3000.0); int i; /* --------------------------------------------------- Print array before sorting --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i++ ) { System.out.println( a[i] ); } SortingTools.SelectionSort(a); System.out.println( "Array after Selection Sort:"); /* --------------------------------------------------- Print array after sorting --------------------------------------------------- */ for ( i = 0 ; i < a.length ; i++ ) { System.out.println( a[i] ); } } } ```

You will get a compile error:

 ```> javac SortBal2.java SortBal2.java:23: SelectionSort(BankAccount[]) in SortingTools cannot be applied to (CheckingAccount[]) SortingTools.SelectionSort(a); ```

• Example Program: (Try it out for yourself !)