# An example of re-using existing programs

• Introduction

• We will continue our discussin on the interesting effect of overriding methods; and it is the cause of a famous effect known as polymorphism

• In this webpage, we will see an example on how to use overriding to re-use some old program to solve a new problem.

• Re-using a program - using the same old program to solve a new problem: the OLD way

• As you know, it is my conviction that humans do something for 2 reasons only:

• they like it or
• they need it...

In computer science, the "complicated" stuff that we do are based on need. (But then again, maybe there's some masochistic computer scientists out there :-))

• To illustrate why people have invented overriding, let us look at an old program that we have written to integrate a function.

• Here is the original program:

 ``` public class MathToolBox { public static double rectangleRule(double a, double b, int n) { double h; // Length of each sub-interval double x_i; int i; double integral; /* --------------------------------------------------- Sanity check: b > a --------------------------------------------------- */ if ( b < a ) { System.out.println("Error: illegal interval "); return(0); // We need to return something.... } /* --------------------------------------------------- The Rectangle Rule Algorithm --------------------------------------------------- */ h = (b-a)/n; integral = 0.0; x_i = a; // First sub-interval point for ( i = 1; i <= n; i++ ) { integral = integral + MyFunction.f(x_i) * h; // ^^^^^^^^^^^^^^^^^^^^^ Area of rectangle x_i = x_i + h; } return ( integral ); } } ```

• So what's the problem ???

• The use of the rectangleRule() is rather clumsy...

 If you need to integrate a new function, you must: Edit the program file MyFunction.java that contains the function. Then compile the whole program... Furthermore, you can ONLY use ONE function at a time

• Example Program: (Demo above code)

• Re-using a program - using the same old program to solve a new problem: the NEW way

• Now let us re-write this program that utilizes overriding...

• Look carefully inside rectangleRule():

• In order to compute the integral (area under a function), it call that function.

• This is the same situation as runMethod1() that calls method1()

• So let's put rectangleRule() and f() in the same class and write them as instance method:

 ``` public class MathToolBox { public double f(double x) { return(x*x - 3); } public double rectangleRule(double a, double b, int n) { double h; // Length of each sub-interval double x_i; int i; double integral; /* --------------------------------------------------- Sanity check: b > a --------------------------------------------------- */ if ( b < a ) { System.out.println("Error: illegal interval "); return(0); // We need to return something.... } /* --------------------------------------------------- The Rectangle Rule Algorithm --------------------------------------------------- */ h = (b-a)/n; integral = 0.0; x_i = a; // First sub-interval point for ( i = 1; i <= n; i++ ) { integral = integral + f(x_i) * h; // ^^^^^^^^^^ Area of rectangle x_i = x_i + h; } return ( integral ); } } ```

• Because instance methods are invoked using an object variable, we need to re-write the test program just a tiny bit:

 ``` public class UseMathToolBox { public static void main(String[] args) { ... MathToolBox dummy = new MathToolBox(); // Make a MathToolBox object ans = dummy.rectangleRule(a, b, n); // Because we need // an instance variable // to invoke instance method System.out.println("ans = " + ans); } } ```

• Example Program: (Demo above code)

• So how do we make rectangleRule() work with another function ???

• First, inherit all methods from the MathToolBox class

• Use method overriding to redirect the rectangleRule() to invoke a new function f()

• Example:

• Suppose we want to intergrate this function f():

 ``` public double f(double x) { return (x + Math.sin(x) ); } ```

• From the above discussion on method overriding, we can achieve the effect as follows:

 ``` public class MyClass extends MathToolBox { public double f(double x) // override f() in MathToolBox { return (x + Math.sin(x) ); } } ```

1. extends inherits both f() and rectangleRule()

2. By defining a new method f() in the sub class, we have overridden the inherited f()

3. As illustrated in the webpage ( click here), the method rectangleRule() will now use the overriding f() - and therefore, rectangleRule() integrate the new function !

The following figure illustrates what is going on:

As you can see, the inherited method rectangleRule() will now invoke the new f()

As a result, the rectangleRule() in the sub class MyClass in compute the integral using the new function !!!

• We do need to write a different program to use the new MyClass class - specifically, we need to create a MyClass object:

 ``` public class UseMathToolBox { public static void main(String[] args) { ... MyClass dummy = new MyClass(); // Make a MyClass object !!! ans = dummy.rectangleRule(a, b, n); // Because we need // an instance variable // to invoke instance method System.out.println("ans = " + ans); } } ```

• Example Program: (Demo above code)

• NOTE:

• In this solution, we do NOT need the source code for MathToolBox.java !!!

• Just try deleting the file MathToolBox.java and use a different function in MyClass.java

• Compile the program without the source for MathToolBox.java and it works !

• Therefore, you can give away or sell the object file MathToolBox.class and the user can NOT know how the program was written !

• Superiority of the new approach

• To see that the new approach in programming is superior, let us write a program that perform integrations on 2 different functions

• Suppose your problem calls to solve 2 integrals numerically and you want to write one program to do it...

Well, using the first approach, it is NOT possible to make the method rectangleRule() integrate 2 different methods...

That is because you need to:

1. Write a program that integrates the first function
2. Then change the program to integrate the second function

You cannot do it in the same program

(And because it is not possible, I cannot demostrate it :-))

• We can easily write a program that integrate 2 function with the second appraoch.

• Example:

Suppose we want to compute the integrals for these 2 functions:

 ``` public double f(double x) { return (x + Math.sin(x) ); } ```

and:

 ``` public double f(double x) { return (x*x + Math.cos(x) ); } ```

• We use the technique above to write 2 classes:

 ``` public class MyClass1 extends MathToolBox { public double f(double x) // override f() in MathToolBox { return (x + Math.sin(x) ); } } ```

And:

 ``` public class MyClass2 extends MathToolBox { public double f(double x) // override f() in MathToolBox { return (x*x + Math.cos(x) ); } } ```

• In the "main" program, we create objects of these two classes - each class will integrate a different function !

 ``` public class UseMathToolBox { public static void main(String[] args) { ... MyClass1 dummy1 = new MyClass1(); // Make a MyClass1 object !!! MyClass2 dummy2 = new MyClass2(); // Make a MyClass2 object !!! ans1 = dummy1.rectangleRule(a1, b1, n1); // Integrates function in MyClass1 ans2 = dummy2.rectangleRule(a2, b2, n2); // Integrates function in MyClass2 ... } } ```