Java How to Program  chapter 6

Methods

Program Modules and Methods; Math Class Methods; Method Definitions; Java API Packages (Class Library); Random Number Generation; Example: Game of Chance; Duration of Identifiers (Scope) and Scope Rules; Recursion; Fibonacci Series; Recursion vs. Iteration; Method Overloading; Methods of the Class JApplet

Other Sources: 
    Free Online Dictionary of Computing.
    The Java Tutorial.
    Java API On-line Documentation.
    Glossary of Java-Related Terms.


Program Modules and Methods

The best way to construct large programs is from small modules that work together to solve a problem or render a service.  Each module contributes its part to the process.  Use of relatively small modules promotes high cohesion, low coupling, and tends to minimize complexity and risk.

Modules in Java are in the form of classes and methods. Classes correspond roughly to the C-language notion of structures, except that the class or class representative (object)  is intended to correspond to a participating entity (an actor) in the process, and contains the functions that report or alter their state.  These functions are the methods for the class or object.  Methods are where any action pertaining to an object or its class is performed.  Programmer's can write their own classes and methods, but in so-doing they generally make extensive use of a rich set of pre-programmed classes and methods that are provided with Java Developer's Kit (JDK).  This library of classes and methods is the Java API [Application Program Interface], aka the Java class library.

The use of methods promotes software reusability, which also helps to minimize bugs by the use of vendor-supplied or field-tested methods.  Each project produces the minimum amount of code necessary to accomplish its aims, using appropriate existing  methods.  The use (or reuse) of methods in multiple places by different programs tends to cause them to have relatively high cohesion and low coupling.

A method is invoked by making a method call (call to the method).  If another class or object's method is being called, a "message" is sent [passed] to the class/object with the method.  The call references the method by name through its class/object by "dot notation".

object.method();
Class.method();

Many methods have arguments, a set of parameters in the form of variables passed in an argument list (aka parameter list) attached to the method call.

object.method(argument1, argument2, ...);

While the main() method of an application ends with a call to System.exit(0);  an applet or other programmer-defined method (other than methods of type void) should end with a return statement.

Just as variables are of two kinds, class and object (or instance), so too methods are either class methods or object methods.  Object methods [aka instance methods] deal with object variables [aka instance variables], variables whose address and value are related related to a particular object, or instance of a class.  Class methods deal with class variables [aka instance variables], variables allocated to the entire class rather than to specific instances of the class.  Class methods are distinguished by the keyword static in their declarations.

Methods that can be invoked from outside the class by other classes must contain the keyword public in their declarations.  If the method is only used by subtypes ("children") of the class in which the method is defined, then one should use the keyword protected instead.


Math Class Methods

The Math class, a part of the java.lang package, contains various methods for mathamatical operations such as bounding, exponential, logarithm, square
root, and trigonometric functions. The Math class also contains approximate values (double precision) of  the two most important real (non-integer) numbers in mathematics, p (Math.PI) the ratio of the circumference of a circle to its diameter, and Euler's number e (Math.E)  which among other things is the base value for natural logarithms.

The java.lang package is imported automatically by the compiler.

To use a method of the Math class, reference the method with the Math. prefix.

To help ensure portability of Java programs, the definitions of many of the numeric functions in this package require that they  produce the same results as certain published algorithms. These algorithms are available from the well-known network library netlib as the package "Freely Distributable Math Library" (fdlibm). These algorithms, which are written in the C programming language, are then to be understood as executed with all floating-point operations following the rules of Java floating-point arithmetic.


Method Definitions

[public] [static] return_value_type method_name( parameter_list )             // the method "declaration"
{
   local variable declarations and statements;
   return expression;
}
 

First Look: GUI Component Containers

A program with a graphical user interface (GUI) has various GUI components.  These components are collected together (and arranged) in a high-level container, which forms a sort of electronic pallet.  Application programs that use Swing GUI components have a JFrame object as their high-level container.  Applets have a JApplet object as their high-level container.  Both JFrames and JApplets have a intermediate-level Container object, the content pane, that is often un-named but is rather obtained from a call to JFrame.getContentPane(); or JApplets.getContentPane(); method call.
Container c = getContentPane();
Low-level GUI components such as text boxes (such as JTextArea), buttons, labels, etc are often added to the Container obtained from getContentPane().

JTextArea is used to put a multi-line text box on the screen.

// Fig. 6.3: SquareInt.java
// A programmer-defined square method
import java.awt.Container;
import javax.swing.*;

public class SquareInt extends JApplet {
   public void init()
   {
      String output = "";

    JTextArea outputArea = new JTextArea( 10, 20 );

      // get the applet's GUI component display area
    Container c = getContentPane();

      // attach outputArea to Container c
    c.add( outputArea );

      int result;

      for ( int x = 1; x <= 10; x++ ) {
         result = square( x );
         output += "The square of " + x +
                   " is " + result + "\n";
      }

    outputArea.setText( output );
   }

   // square method definition
   public int square( int y )
   {
      return y * y;
   }
}


Java API Packages (Class Library)

The Java application programming interface [Java API] defines a large number of pre-programmed classes and methods.  These are grouped together in packages which form libraries of of functionally similar or related classes.  (The major packages are listed in Java How to Program [3rd edition] on pp 215-218).


Random Number Generation

For programming processes which contain "random" events or events whose outcome cannot be determined except as being one of a range of possilities, generation of pseudo-random numbers is essential.  This includes modelling or simulating many real-world processes and scenarios, and the vast majority of games.  Java provides a Math function for generating random numbers, Math.random().

For now, we assume that any potential possibility is as likely as any other.  In these cases Math.random()is adequate.  More complex cases where there is a non-linear probability distribution are handled by weights or other techniques [fudge] applied to the generated numbers, by using the Random class from the util package for "normal" or Gaussian distributions, or by supplying your own value generation function.

// Fig. 6.7: RandomInt.java
// Shifted, scaled random integers
import javax.swing.JOptionPane;

public class RandomInt {
   public static void main( String args[] )
   {
      int value;
      String output = "";

      for ( int i = 1; i <= 20; i++ ) {
         value = 1 + (int) ( Math.random() * 6 );
         output += value + "  ";

         if ( i % 5 == 0 )
            output += "\n";
      }

      JOptionPane.showMessageDialog( null, output,
         "20 Random Numbers from 1 to 6",
         JOptionPane.INFORMATION_MESSAGE );

      System.exit( 0 );
   }
}


Example: Game of Chance

Craps

Rules of Play:
A player rolls two dice.
7 or 11 on first throw -- player wins.
2, 3, or 12 ("craps") on first throw -- player looses (house wins).
4, 5, 6, 8, 9, or 10 on first throw -- this becomes player's points.  Player rolls until they make their points on a roll (win) or roll a 7 (loose).


// Fig. 6.9: Craps.java
// Craps
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Craps extends JApplet implements ActionListener {
   // constant variables for status of game
   final int WON = 0, LOST = 1, CONTINUE = 2;

   // other variables used in program
   boolean firstRoll = true;   // true if first roll
   int sumOfDice = 0;          // sum of the dice
   int myPoint = 0;   // point if no win/loss on first roll
   int gameStatus = CONTINUE;  // game not over yet

   // graphical user interface components
   JLabel die1Label, die2Label, sumLabel, pointLabel;
   JTextField firstDie, secondDie, sum, point;
   JButton roll;

   // setup graphical user interface components
   public void init()
   {
      Container c = getContentPane();
      c.setLayout( new FlowLayout() );

      die1Label = new JLabel( "Die 1" );
      c.add( die1Label );
      firstDie = new JTextField( 10 );
      firstDie.setEditable( false );
      c.add( firstDie );

      die2Label = new JLabel( "Die 2" );
      c.add( die2Label );
      secondDie = new JTextField( 10 );
      secondDie.setEditable( false );
      c.add( secondDie );

      sumLabel = new JLabel( "Sum is" );
      c.add( sumLabel );
      sum = new JTextField( 10 );
      sum.setEditable( false );
      c.add( sum );

      pointLabel = new JLabel( "Point is" );
      c.add( pointLabel );
      point = new JTextField( 10 );
      point.setEditable( false );
      c.add( point );

      roll = new JButton( "Roll Dice" );
      roll.addActionListener( this );
      c.add( roll );
   }

   // call method play when button is pressed
   public void actionPerformed( ActionEvent e )
   {
      play();
   }

   // process one roll of the dice
   public void play()
   {
      if ( firstRoll ) {             // first roll of the dice
         sumOfDice = rollDice();

         switch ( sumOfDice ) {
            case 7: case 11:         // win on first roll
               gameStatus = WON;
               point.setText( "" );  // clear point text field
               break;
            case 2: case 3: case 12: // lose on first roll
               gameStatus = LOST;
               point.setText( "" );  // clear point text field
               break;
            default:                 // remember point
               gameStatus = CONTINUE;
               myPoint = sumOfDice;
               point.setText( Integer.toString( myPoint ) );
               firstRoll = false;
               break;
         }
      }
      else {
         sumOfDice = rollDice();

         if ( sumOfDice == myPoint )    // win by making point
            gameStatus = WON;
         else
            if ( sumOfDice == 7 )       // lose by rolling 7
               gameStatus = LOST;
      }

      if ( gameStatus == CONTINUE )
         showStatus( "Roll again." );
      else {
         if ( gameStatus == WON )
            showStatus( "Player wins. " +
               "Click Roll Dice to play again." );
         else
            showStatus( "Player loses. " +
               "Click Roll Dice to play again." );

         firstRoll = true;
      }
   }

   // roll the dice
   public int rollDice()
   {
      int die1, die2, workSum;

      die1 = 1 + ( int ) ( Math.random() * 6 );
      die2 = 1 + ( int ) ( Math.random() * 6 );
      workSum = die1 + die2;

      firstDie.setText( Integer.toString( die1 ) );
      secondDie.setText( Integer.toString( die2 ) );
      sum.setText( Integer.toString( workSum ) );

      return workSum;
   }
}

The program illustrates

Components are added to a Container object (as described above) and then

How to Implement an Event Handler

Every event handler requires three bits of code:

1. In the declaration for the event handler class, code that specifies that the class either implements a listener interface or extends a class that implements a listener interface. For example:
               public class MyClass implements ActionListener {

2. Code that registers an instance of the event handler class as a listener upon one or more components. For example:
              someComponent.addActionListener(instanceOfMyClass);

3. Code that implements the methods in the listener interface. For example:
               public void actionPerformed(ActionEvent e) {
                   ...//code that reacts to the action...
               }

More information on event handling is available from The Java Tutorial.


Duration of Identifiers (Scope) and Scope Rules

Scope of a variable is determined by where it is declared.  Variables declared in methods (at the method instruction level) are valid for the duration of the method.


Recursion

Recursion is where a method can call itself, either directly or indirectly through an intermediary method.  Recursion breaks a complex problem or case into two simpler cases, one simple and the other possibly not so simple.  Each recursion call checks for one or more "base cases".  A base case is a condition under which the routine can return a value without calling itself.  If the more complex turns out to be complex, that piece is resubmitted where it is further divided.  The process goes on until all pieces are straightforward and cause the recursion routine to return an answer.
 

Example

// Fig. 6.12: FactorialTest.java
// Recursive factorial method
import java.awt.*;
import javax.swing.*;

public class FactorialTest extends JApplet {
   JTextArea outputArea;

   public void init()
   {
      outputArea = new JTextArea();

      Container c = getContentPane();
      c.add( outputArea );

      // calculate the factorials of 0 through 10
      for ( long i = 0; i <= 10; i++ )
         outputArea.append(
            i + "! = " + factorial( i ) + "\n" );
   }

   // Recursive definition of method factorial
   public long factorial( long number )
   {
      if ( number <= 1 )  // base case
         return 1;
      else
         return number * factorial( number - 1 );
   }
}


Fibonacci Series

A series of numbers that starts with 0 and 1, with subsequent numbers being the sum of the previous two:
0, 1, 1, 2, 3, 5, 8, 13, 21, ...

A program that computes the nth number in this series is an example of recursion.  The algorithm is
Base cases:
fibonacci(0) = 0
fibonacci(1) = 1
Recursive formula:
fibonacci(n) = fibonacci(n-1) + fibonacci(n-2)
 

// Fig. 6.13: FibonacciTest.java
// Recursive fibonacci method
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class FibonacciTest extends JApplet
             implements ActionListener {
   JLabel numLabel, resultLabel;
   JTextField num, result;

   public void init()
   {
      Container c = getContentPane();
      c.setLayout( new FlowLayout() );

      numLabel =
         new JLabel( "Enter an integer and press Enter" );
      c.add( numLabel );

      num = new JTextField( 10 );
      num.addActionListener( this );
      c.add( num );

      resultLabel = new JLabel( "Fibonacci value is" );
      c.add( resultLabel );

      result = new JTextField( 15 );
      result.setEditable( false );
      c.add( result );
   }

   public void actionPerformed( ActionEvent e )
   {
      long number, fibonacciValue;

      number = Long.parseLong( num.getText() );
      showStatus( "Calculating ..." );
      fibonacciValue = fibonacci( number );
      showStatus( "Done." );
      result.setText( Long.toString( fibonacciValue ) );
   }

   // Recursive definition of method fibonacci
   public long fibonacci( long n )
   {
      if ( n == 0 || n == 1 )  // base case
         return n;
      else
         return fibonacci( n - 1 ) + fibonacci( n - 2 );
   }
}


Recursion vs. Iteration

Recursion refers to a method (function) calling itself to solve a problem in part by converging or arriving at a "base case".  The original call is still open.  Iteration refers to the repeated application of an self-contained algorithm to converge on a solution to a problem.  One (high-level) call is open.

Iteration uses explicit repetition control structures.  Recursion acheives repetition implicitly through repeated calls.  Both require a termination mechanism.  Recursion algorithms tend to be less straightforware and thus more prone to subtle bugs, and they can incur greater overhead (processor time and memory) from repeated function calls -- but they do have their appropriate place in the programmer's toolkit.


Method Overloading

Several methods of the same name may be defined so long as they have different sets of arguments or parameters (based on their number, type, and order).  This practice is refered to as overloading the method.  Sometimes, the return type of each overloaded method is different.  Another reason for doing this is to allow for some parameters to take on some default value rather than forcing the program writer to explicitly code a parameter s/he neither knows or cares about


Methods of the Class JApplet

Typical methods of an applet correspond to the applets lifecycle (init, start, stop, destroy) and to painting its Graphics content.

Because JApplet is inherited from java.awt.Component, it implements the paint method, the repaint method, and other GUI component methods, and exhibites GUI component-like behavior -- responds to events like a GUI component.



http://www.rscc.cc.tn.us/faculty/bell/Cst209/jhtp6.html