# A widely used technique to write re-usable programs

• Introduction

• We will use a useful programming technique to introduce the concept of interface

• The use of an interface allow us to seperate

• computer algorithm (i.e., the computer program) from

• the type of data

• In doing so, we can re-apply (re-use) the SAME computer algorithm (i.e., the computer program) on different type of data very easily.

• This material ties in with inheritance and polymporphism

• In the previous discussion, we use inheritance to clone a class and then use polymporphism to allow the new class to exhibit a different behavior from the super class.

• Here, we turn the table around:

• Suppose we do a similar task on many different classes of items (e.g.: sorting integers, sorting String, sorting phone books)

• We can use inheritance to bring all the difference classes into a single class

• If so, the polymorphism mechanism can help us stop repeating/copying programs !!!

• Preliminary discussion...

• Consider the following Bubblesort algorithm (on integers) that we have studied in this webpage ( click here )

 ``` input: int[] data; // Containing an array of integers that need sorting boolean done; // The variable will tell us if we need to continue done = false; while ( ! done ) { done = true; // Set to true to detect if some pair is swapped for "every pair of values in data" do { if ( "pair of value is out of order" ) { "swap the pair of values"; done = false; // Detect a swap - need to continue... } } // NOTE: done will be "true" if all pair were in correct order ! } ```

• The following is the Bubblesort program that sorts an array of integers:

 ``` public class MyUtil { public static void sort(int[] data) { int i; boolean done; // The variable will tell us if we need to continue int help; // Help variable must have the same type as data /* ------------------------ Bubble Sort Algorithm ------------------------ */ done = false; while ( ! done ) { done = true; // Set to true to detect if some pair is swapped for (i = 0; i <= data.length - 2; i++) { if ( data[i] > data[i+1] ) { help = data[i]; data[i] = data[i+1]; data[i+1] = help; done = false; // Detect a swap - need to continue... } } } } } ```

• Example Program: (Demo above code)

• We have also written a Bubblesort program to sort and array of strings:

 ``` public class MyUtil { public static void sort(String[] data) { int i; boolean done; // The variable will tell us if we need to continue String help; // Help variable must have the same type as data /* ------------------------ Bubble Sort Algorithm ------------------------ */ done = false; while ( ! done ) { done = true; // Set to true to detect if some pair is swapped for (i = 0; i <= data.length - 2; i++) { if ( data[i].compareTo(data[i+1]) > 0 ) { help = data[i]; data[i] = data[i+1]; data[i+1] = help; done = false; // Detect a swap - need to continue... } } } } } ```

• Example Program: (Demo above code)

• A moment of pondering....

• As you can see, there is VERY little difference between the two different version of programs....

• The following are the VERY minor changes that we need to make to make BubbleSort to sort an array of a different type:

 Change the type of the help variable (to the type of the data being sorted --- help is used to exchange the values) Use an approriate compareTo() method --- this method tells us whether 2 data items are out of order

• The \$64,000 question is:

 Can we use the inheritance mechanism and polymorphism to re-write the above program so that ONLY ONE sorting method is needed (to sort both integers and Strings)

• Designing a uniform solution

• First, I like to describe in simple terms what we what to achieve...

• We saw we needed TWO (slightly) different programs to sort TWO different types of data (one for integers and one for Strings).

• In fact, the situation is such that:

• We need to write a NEW program whenever we want to sort a different type of data

• We want to be unreasonable:

• We want to use the SAME program to sort any type of data

• Obviously, in order to sort a set of data, the data must satisfy some basic requirement(s) .

• Clearly, in order to put items in a particular ordering, the items must be comparable.

• So let's see if we can write a sort program using generic Comparable objects

• Suppose we want to sort an array of "Comparable" items (objects), this would be the sorting program that we would write:

 ``` public class MyUtil { public static void sort(Comparable[] data) { int i; boolean done; // The variable will tell us if we need to continue Comparable help; // Help variable must have the same type as data /* ------------------------ Bubble Sort Algorithm ------------------------ */ done = false; while ( ! done ) { done = true; // Set to true to detect if some pair is swapped for (i = 0; i <= data.length - 2; i++) { if ( data[i].compareTo(data[i+1]) > 0 ) { help = data[i]; data[i] = data[i+1]; data[i+1] = help; done = false; // Detect a swap - need to continue... } } } } } ```

• Notice that within the sort() program, we have invoked:

 ``` data[i].compareTo(data[i+1]) ```

• From the use of the compareTo() method, the signature of this method is as follows:

 ``` public int compareTo( Comparable x ) { // compare "this" object against object "x" // // Return the value 0 when "this" object and object "x" rank equally // Return the value > 0 when "this" object preceeds object "x" // Return the value < 0 when "this" object follows object "x" } ```

• So here is an example of the class Comparable:

 ``` public class Comparable { public int compareTo( Comparable x ) { return(0); // Just return something // We will ALWAYS override this method !!! } } ```

• Now you may wonder why we would put a useless method compareTo() inside this class...

• The reason is conflicting requirements:

1. On the one hand, we know that in order to provide information to the Bubblesort algorithm, we need to provide the method compareTo()

2. On the other hand, for a completely generic type (without any information on what the type contains), we cannot write the details about the compareTo() method.

• But that is OK, because the reason is we will ALWAYS override the compareTo() method - so that the useless method inside Comparable will never used

It is there so that we can exploid the polymorphism ability of Java

• Example Program: (Demo above code)

You can compile the program, but it does not do anything useful... yet !!!

• Applying inheritance and polymorphism to make the generic sort program sort INTEGER type of data

• Believe it or not, what we have written above can be used to sort any type of data !!!

I will illustrate what you need to do to so integer type data.

• Let me first illustrate what's going on inside the sort() method:

• Now, suppose we define a subclass IntComparable using Comparable as superclass:

 ``` public class IntComparable extends Comparable { } ```

• Add an instance integer variable value to the class:

 ``` public class IntComparable extends Comparable { private int value; } ```

• And override the useless method compareTo() to compare the value variables:

 ``` public class IntComparable extends Comparable { public int compareTo( Comparable x ) { // method compare "this.value" against "x.value" !!! if ( this.value > x.value ) return (1); // > 0 means out of order else if this.value == x.value ) return (0); // 0 means equal else return (-1); // <0 means in correct order } private int value; } ```

• Now, consider what the polymorphic method invocation will do, if we change Comparable to IntComparable:

 ``` IntComparable[] data; if ( data[i].compareTo(data[i+1]) > 0 ) .... ```

• The polymorphic method invocation will invoke the overridden method compareTo() inside the new class:

• This looks very promissing... BUT... we we try to compile the program, we get ERRORS !!!

Example Program: (Demo above code)

The compiler complains that:

 ``` IntComparable.java:13: cannot find symbol symbol : variable value location: class Comparable if ( this.value < x.value ) ^ ```

The reason is:

• Although we passed in an IntComparable object to be compared against another IntComparable object, the parameter variable x of the method is of type Comparable

• The superclass Comparable has no knowledge of the newly defined instance variable int value;

Solution:

• Convert the type Comparable back to a IntComparable type !

• Notice that this conversion is dangerous; because the type IntComparable can perform more functions than the type Comparable

(Converting from IntComparable to Comparable is safe because we can never as an IntComparable object to do something that it could not do because a IntComparable can do everything that a Comparable object can do.

The reverse is not true, because after converting a Comparable object to an IntComparable, we may tell the Comparable object to do something it it cannot do !!!

• Because the conversion from superclass to subclass is NOT safe, Java requires explicit permission from the programmer:

 ``` public class IntComparable extends Comparable { public int compareTo( Comparable x ) { // method compare "this.value" against "x.value" !!! IntComparable z; z = (IntComparable) x; if ( this.value > z.value ) return (1); // > 0 means out of order else if this.value == z.value ) return (0); // 0 means equal else return (-1); // <0 means in correct order } private int value; } ```

• Now, using the sort method on integers is now as easy as follows:

 ``` public static void main(String[] args) { int i; IntComparable[] A = new IntComparable[5]; A[0] = new IntComparable(20); A[1] = new IntComparable(67); A[2] = new IntComparable(12); A[3] = new IntComparable(98); A[4] = new IntComparable(45); MyUtil.sort(A); for (i = 0; i < 5; i++) System.out.println(A[i] + " "); } ```

Example Program: (Demo above code)

• Applying inheritance and polymorphism to make the generic sort program sort STRING type of data

• Believe it or not, it is as easy to sort STRING type of data !!!

• First, inherit from Comparable (and it will help to name the new class StringComparable):

 ``` public class StringComparable extends Comparable { } ```

• Then add an instance variable value to the class, but now with the type String (because afterall, we want to sort Strings):

 ``` public class StringComparable extends Comparable { private String value; } ```

• And override the useless method compareTo() to compare the String value variables:

 ``` public class StringComparable extends Comparable { public int compareTo( Comparable x ) { StringComparable z; z = (StringComparable) x; // Convert !! // method compare "this.value" against "z.value" !!! return ( (this.value).compareTo( z.value ); ^^^^^^^^^^ ^^^^^^^ String 1 String 2 } private String value; } ```

• Now, consider what the polymorphic method invocation will do, if we change Comparable to StringComparable:

 ``` StringComparable[] data; if ( data[i].compareTo(data[i+1]) > 0 ) .... ```

• The polymorphic method invocation will invoke the overridden method compareTo() inside the StringComparable class:

• Now, using the sort method on integers is now as easy as follows:

 ``` public static void main(String[] args) { int i; StringComparable[] A = new StringComparable[5]; A[0] = new StringComparable("Hello"); A[1] = new StringComparable("Good-bye"); A[2] = new StringComparable("Hi, There"); A[3] = new StringComparable("Have a nice day"); A[4] = new StringComparable("That's all folks"); MyUtil.sort(A); for (i = 0; i < 5; i++) System.out.println(A[i] + " "); } ```

Example Program: (Demo above code)

• Applying inheritance and polymorphism to make the generic sort program sort ITEM type of data

• Can't believe it is that easy ?

So want to see how to sort an array of ITEM type of data ?

• First, let me remind you of the Item class (telephone book):

 ``` public class Item { ... private String name; private String phone; private int age; } ```

In fact, we have written a sort program on this type of data - discussed in this webpage: click here

Note 1: I have removed some methods that I will not used from the class.

Note 2: I will also rename the class to reflect that it inherits from Comparable

• Now, as you know, we must inherit from Comparable (and it will help to name the new class ItemComparable):

 ``` public class ItemComparable extends Comparable { private String name; private String phone; private int age; } ```

• We don't need to add instance variables to the class, because they have been defined for us !

 ``` public class ItemComparable extends Comparable { private String name; (unchanged) private String phone; private int age; } ```

• And override the useless method compareTo() to compare the Item value variables...

Now, here we need to decide how to rank the Item objects.

I will assume that we rank them by name:

 ``` public class ItemComparable extends Comparable { public int compareTo( Comparable x ) { ItemComparable z; z = (ItemComparable) x; // Convert !! // method compare "this.value" against "z.value" !!! return ( (this.name).compareTo( z.name ); ^^^^^^^^^ ^^^^^^ String 1 String 2 } private String name; private String phone; private int age; } ```

• Now, the polymorphic method invocation will compare the values in the name field

• Using the sort method on an array of Item objects is now as easy as follows:

 ``` public static void main(String[] args) { int i; ItemComparable[] A = new ItemComparable[5]; A[0] = new ItemComparable("James", "111-1111", 24); A[1] = new ItemComparable("Adam", "123-4567", 19); A[2] = new ItemComparable("Bert", "876-8726", 35); A[3] = new ItemComparable("Peter", "345-9822", 43); A[4] = new ItemComparable("Mary", "876-9991", 27); MyUtil.sort(A); for (i = 0; i < 5; i++) System.out.println(A[i] + " "); } ```

Example Program: (Demo above code)

• Self Check

• What would happen if we change the compareTo() in the ItemComparable class to:

 ``` public int compareTo( Comparable x ) { ItemComparable z; z = (ItemComparable) x; return ( this.age - z.age ); } ```