On
completion of this section you will be familiar with
If we look
back at Listing 1.1 we had a very simple programme that was very easy to follow
since the individual lines of the input, processing and output followed each
other in a very logical sequence from top to bottom. Of course this programme
was so simple that it was of no use in real life. In order to make it more
useful we added an if..else
construct in order to calculate the tax and a select..case construct in order to calculate the superannuation.
The
addition of those constructs made the programme more useful and more realistic,
but consequently we lost the logical line by line simplicity of the original.
Our aim in this chapter is to look at retaining the original simplicity of the
programme while at the same time keeping the extra functionality and usefulness
of the if..else and select..case constructs. We do this by
using methods.
As well as
making our programme easier to read methods have another function. Suppose that
there was a group of lines of a programme that were required to be used in
different parts of the programme, then, we can simply write out the lines of
code separately for each part of the programme where they are required. This
has two drawbacks:
Firstly the
more often we retype the lines of code the more likely we are to make a mistake
in one of them. This would cause inconsistency in the application.
If the
routine needs to be altered then we have to make the same alteration wherever
the routine occurs. This has the inherent danger that we may miss out one of
the instances of the routine.
The other
alternative is to write the group of lines together only once and then to call
that group whenever we need to use them. This has the following advantages:
It saves
both saving typing time and storage space.
As we write
them only once the danger of error is minimised.
If the
routine needs to be changed then the change has to be done only once
In order to
examine the use of methods we shall revisit our payroll application once more
and look at how methods can simplify the application for us.
The code
shown below is simply listing 3.2 broken into methods. Below the code we will
examine its new construction and how it operates.
Listing 5.1
|
1 |
public class Untitled1 |
|
2 |
{ |
|
3 |
public
static void main(String[] args) |
|
4 |
{ |
|
5 |
double
hours,rate,gross,tax,nett,superAmount; |
|
6 |
int
superCode; |
|
7 |
hours
= 40; |
|
8 |
rate =
10; |
|
9 |
superCode = 9; |
|
10 |
gross
= calculateGross(hours, rate); |
|
11 |
tax =
calculateTax(gross); |
|
12 |
superAmount = calculateSuper(gross, superCode); |
|
13 |
nett =
calculateNett(gross, tax, superAmount); |
|
14 |
showData(hours,rate, gross, tax,
superAmount, nett); |
|
15 |
} |
|
16 |
public
static double calculateGross(double h, double r) |
|
17 |
{ |
|
18 |
double
g; |
|
19 |
g = h
* r; |
|
20 |
return
g; |
|
21 |
} |
|
22 |
public
static double calculateTax(double g) |
|
23 |
{ |
|
24 |
double
t; |
|
25 |
if(g<=500) |
|
26 |
t
= g * .25; |
|
27 |
else |
|
28 |
t
= 125 +(g - 500) * .33; |
|
29 |
return
t; |
|
30 |
} |
|
31 |
public
static double calculateSuper(double g, int sc) |
|
32 |
{ |
|
33 |
double
sa; |
|
34 |
switch(sc) |
|
35 |
{ |
|
36 |
case 0: |
|
37 |
sa = 0; |
|
38 |
break; |
|
39 |
case 1: |
|
40 |
case 2: |
|
41 |
case 3: |
|
42 |
sa = g * .05; |
|
43 |
break; |
|
44 |
case 4: |
|
45 |
sa = g * .07; |
|
46 |
break; |
|
47 |
case 5: |
|
48 |
case 6: |
|
49 |
sa = g * .1; |
|
50 |
break; |
|
51 |
case
7: |
|
52 |
case 8: |
|
53 |
case 9: |
|
54 |
sa = g * .2; |
|
55 |
break; |
|
56 |
default: |
|
57 |
sa = -1; |
|
58 |
} |
|
59 |
return
sa; |
|
60 |
} |
|
61 |
public
static double calculateNett(double g, |
|
62 |
double
t, double sa) |
|
63 |
{ |
|
64 |
double
n; |
|
65 |
n = g
- t - sa; |
|
66 |
return
n; |
|
67 |
} |
|
68 |
public
static void showData(double h, double r, double g, |
|
69 |
double t,
double sa, double n) |
|
70 |
{ |
|
71 |
System.out.println("Hours " + h); |
|
72 |
System.out.println("Rate " + r); |
|
73 |
System.out.println("Gross " + g); |
|
74 |
System.out.println("Tax " + t); |
|
75 |
System.out.println("Superannuation " + sa); |
|
76 |
System.out.println("Nett " + n); |
|
77 |
|
|
78 |
} |
|
79 |
} |
The first
thing that we notice about listing 5.1 is that the method main has shrunk considerably in size. It now spans only the lines 3
– 15. Down as far as line 9 it is no
different than its predecessor.
At line 10,
however, the way we calculate the gross pay has altered considerably. Here the
method calculateGross is called.
Using the values of the variables hours
and rate the method calculates the
value of the gross pay and stores the result in the variable gross. The values of the tax,
superannuation contribution and the nett pay is calculated in a similar manner
in lines 11 – 13. finally at line 14 another method, showData is called to display the results of the calculation.
In the
introduction to this chapter we mentioned that methods can make the code
simpler to read and makes the logic of the programme more apparent. In our
case, by naming our variables and our methods in a sensible manner, we can look
at our code from line 7 to line 14 and see that firstly hours, rate and
superannuation code are given values (lines 7 – 9), the gross pay is calculated
using the hours and rate as reference (line 10), the tax is calculated using
the gross as reference (line 11), the superannuation amount is calculated using
gross and the superannuation code as reference(line 12) and finally in line 13
the nett is calculated using gross, tax and the superannuation amount as
references.
Before
examining in detail how our new methods work let us spend a little time on the
methd main and its variables. those
variables are declared in lines 5 and 6.
those lines are inside the body of the method and for this reason they
are regarded as being local to that
method. What this means is that those
variables, that is hours, rate, gross,
tax, nett, superAmount and superCode
are only visible between lines 15 and 14 and are invisible to the rest of the
programme. The rest of the programme
needs to use the values of those variables and we shall examine how that is
done.
Our first
method call is at line 10 where the calculateGross
method is called. This line is equivalent to saying jump to the calculateGross method, take the values
of the variables hours and rate with you so that the value of the
gross can be calculated, and once the method has completed store the result in
the variable gross. When the method main is running and a call is made to calculateGross then the method main temporarily stops execution and
control passes to the method calculateGross,
which begins at line 16.
Here at
line 16 let us examine the makeup of this method and how coupling with main occurs. Notice that following the name of the method calculateGross there is (double h, double r). Those are referred to as arguments. Linking this to the call to the method in line 10, what
happens is that the value of the variable hours
is copied into the argument h and
the value of the variable rate is
copied into the argument r. Thus those two arguments will have values of
40 and 10 respectively.
Since the
argument h and r are declared as part of the method calculateGross they are visible to the code of that method, in
other words they are visible between lines 18 and 20. At line 18 a local variable
g is declared. This will be used to
temporarily store the value of the gross pay. In line 19 that gross pay is in
fact calculated from the values of h and r and stored in g. Since g is a local
variable of calculateGross it is
invisible to the rest of the code, including the method main. The value stored in g
must, however, be copied into the variable gross
which resides in the method main.
This is achieved by the return
statement of line 20. This statement
is equivalent to terminate the method calculateGross, then return back to the
line that called that method in the first place and store the value of the
variable g in that method. Thus calculateGross finishes, control is
passed back to line 10 and the value of g
is stored in the variable gross.
Now that we
have examined the sequence of execution and the passing of data that occurs
when a method is called let us look at some of the things that must be in place
for this to happen. In line 10 where calculateGross
is called, it takes with it the values of the variables hours and rate as
arguments. Those two variables have been
declared as double. If we look at
the definition of calculateGross
itself in line 16 we notice that its two arguments h and r are declared as
being of type double. Thus the data type of the values passed to a
method must match the type of the arguments of that method.
Still at
line 16, the keyword before the name of the method is also double. Thus means that this
method will return a value of the data type double. In line 20 we see that this indeed does occur
since the variable g has been
declared as double.
One more
point! In the above example the value returned at line 20 will end up being
stored in the variable gross at line
10. Again this variable is double to
accommodate the data that is to be passed to it by calculateGross.
The exact
same logic that we have described for calculateGross
can be applied to calculateTax,
calculateSuper and calculateNett as well. Where they are
called in lines 11 – 13 they are on the right hand side of an assignment
operator, which means that the values they return are stored in the variables
that are on the left hand side of the same operator. Again the number and types
of values they take with them correspond with the number and type of arguments
that are defined where the methods themselves are declared further down. Finally notice that the last line of code in
each method begins with the keyword return
so that the value calculated by the method can be returned back to the main
programme.
Of all of
the methods we have created for this exercise one differs from all the others.
This is the method showData. First
of all, where it is called in line 14, it is not on the right side of an
assignment operator. Next when we look at its definition beginning at line 68
we notice the keyword void before
the name of the method. This means that the method does not return any value
and when we look at the body of the method we notice that they keyword return does not occur there. In summary
a void method is used simply to
process data where the result of a calculation is not required to be sent back
to the main programme.
In the
first chapter when we were examining the method main, we said that as we progressed through the course we would
explain the keywords public, static,
void. We are now in the position of
being able to explain one of them – void.
So far we
have noticed that the method main
called all of the other methods. Some returned values back to it and one did
not. In fact any method can call any other method apart from main. main cannot be called by any other method. The reason for this is
tha when we run any Java application the system itself calls main as the start-up part of our
application and thus since no method has called it, it cannot return any value
back. Consequently it has to be declared as void.
Methods
are used both to avoid repetition of code within a programme and also in order
to make the logic of the programme easier to follow. Data is passed by the
calling routine to a method using arguments.
The data passed and the arguments must match each other in type. There
are two types of methods: those that return a value and those that don’t.
The latter must be declared as void
while the former must have the name of the data type immediately before the
name of the method. This is referred
to as the return type of that method. Those that return a value must contain
the keyword return. The data returned must match the
return type of the method.
Copy Exercise
5.1 into your computer, then compile and run it. Try tracing the execution
of the programme to ensure you understand how control is passed between main
and the other methods.
Next create
a new method in your application called startUp.
It will be a void method that takes no arguments. Now copy all of the code of method main into startUp and insert a call to startUp
into main. The output of your
programme should not alter in any way.
1)
How
does the use of methods lead to having better written programmes?
2)
What
does an argument mean as far as methods are concerned?
3)
What
co-relation must exist between the arguments and the data passed to them?
4)
There
are two types of methods. What are they?
5)
Describe
in detail the similarities and differences between the two types of methods you
identified in question 4
Modify
Exercise 3.3 as follows:
1)
Put
the calculation of the price of a single mower, discount, price
after discount, gst, price including gst and total cost of sale into separate methods. The names
and details of the methods should be as follows:
a.
calculateMowerPrice. This
method will have a single argument and should be passed the mower
category. A switch case construct inside
it should calculate the mower price using the value of the mower category. This value should then be returned back to
the main programme. You may simply copy
the appropriate code from the main programme into the method.
b.
calculateDiscount. This method will have two arguments – one to hold the value of the price
of a mower and another to hold the value of the amount sold. The body of the method uses an if..else
construct to determine if the discount should be zero or 5% of the mower price
c.
calculatePriceAfterDiscount. This
method will have two arguemts, one for the price before
discount and the other for the discount itself.
The method simply adds the values of the two arguments together and
returns the result back to the main programme.
d.
calculateGST. This method is passed only one argument:
one that holds the value of the price after discount. The method simply calculates 10% of this
value and returns the result to the main programme.
e.
calculatePriceIncGST. This method
is passed two arguments: one for holding the price after discount and the other
holding the value of the GST. The method
simply adds the two values and returns the result to the main programme.
f.
calculateTotal. This method has two arguments: one for
holding the price including GST and the other holding the amount sold. The method simply multiplies the two values
together and returns the result to the main programme.
g.
showData.
This method does not return any values. It has seven arguments that hold the values
of the amount sold, the price of the mower, the discount, the price after
discount, gst, price
including gst and the customer total. The method simply prints those values using
the System.out.println() method.
2)
Next
call those methods from the method main, ensuring that the appropriate
arguments are passed to them and that they themselves pass the appropriate
values back.
3)
Ensure
that no coding remains in the method main apart from giving initial values to
the amount sold and the mower category.
4)
Use
the table below to test the new version of your programme.
|
Input
Data |
Expected
output |
Actual
output |
|||||||||||
|
Category |
Amount Sold |
Price of L’mower |
Discount |
Price
after discount |
GST |
Price inc GST |
Customer Total |
Price of L’mower |
Discount |
Price
after discount |
GST |
Price inc GST |
Customer Total |
|
1 |
12 |
100 |
5 |
95 |
9.50 |
104.50 |
|
|
|
|
|
|
|
|
2 |
9 |
250 |
0 |
250 |
25 |
275 |
|
|
|
|
|
|
|
|
3 |
20 |
400 |
20 |
380 |
38 |
418 |
|
|
|
|
|
|
|
|
4 |
16 |
600 |
30 |
570 |
57 |
627 |
|
|
|
|
|
|
|
|
5 |
3 |
750 |
0 |
750 |
75 |
825 |
|
|
|
|
|
|
|
|
6 |
5 |
800 |
0 |
800 |
80 |
880 |
|
|
|
|
|
|
|