3 Messages and Methods

Let’s return to the object-oriented concept discussion. You can extend the COBOL example to explore some other Java concepts.

Image

A subroutine call can be viewed as a message, passed from one object to another.

When you called MYSUB from CALLER, you prepared some information (in TEXT-STRING) and asked MYSUB to evaluate it. In object-oriented (OO) terms, this is sometimes referred to as message passing. That is, CALLER passed a particular type of message to MYSUB.

In Java, objects can send messages to other objects. In almost all respects, this is similar to a subroutine call. However, objects typically support more than one type of message. COBOL subroutines can do this, too, but it takes a little planning.

In the example so far, MYSUB can only support one message type (i.e., evaluate TEXT-STRING). Suppose you want MYSUB to support multiple functions that are in some way related. You can do this by extending the MYSUB-CONTROL to include an ACTION-SWITCH. This item is used by the calling program to specify the function requested.

MYSUB COBOL

MYSUB is extended to add an action switch to its interface.

IDENTIFICATION DIVISION.
PROGRAM-ID. MYSUB.
DATA DIVISION.
WORKING-STORAGE SECTION.
************************************************************************
* This routine accepts a text item as a parameter and evaluates the    *
* text. If the text is all spaces, MSG-SIZE will be set to 0. Else,    *
* MSG-SIZE will be set to                                              *
* Only if requested, the text item will also be stored                 *
* in the passed control structure.                                     *
************************************************************************
LINKAGE SECTION.
01 MYSUB-CONTROL.
    03   MYSUB-ACTION-SWITCH     PIC X.
         88 MYSUB-ACTION-EVALUATE          VALUE "E".
         88 MYSUB-ACTION-SET-AND-EVALUATE  VALUE "S".
    03   MSG-TEXT                PIC X(20).
    03   MSG-SIZE                PIC 9(8).

01 TEXT-STRING              PIC X(20).

PROCEDURE DIVISION USING MYSUB-CONTROL, TEXT-STRING.

MYSUB-INITIAL SECTION.
MYSUB-INITIAL-S.
*   Perform the subroutine's function.
     IF TEXT-STRING = SPACES
          MOVE 0 TO MSG-SIZE
     ELSE
          MOVE 1 TO MSG-SIZE.
*   Evaluate if this additional function was requested.
*   If yes, perform it (i.e., save the string in TEXT-STRING).

    IF MYSUB-ACTION-SET-AND-EVALUATE
         MOVE TEXT-STRING TO MSG-TEXT.

EXIT-PROGRAM.
     EXIT PROGRAM.

Using this interface definition, the CALLER program can ask MYSUB to store the TEXT-STRING in MSG-TEXT. It can also ask MYSUB to evaluate TEXT-STRING in order to determine whether it contains only spaces. The result is stored in MSG-SIZE.

CALLER COBOL

Alternatively, the CALLER can ask MYSUB to simply perform the evaluation and not store the TEXT-STRING in MSG-TEXT. This would be a slight variation on MYSUB’s basic function. CALLER can then request either of these two functions by setting ACTION-SW to the appropriate value. Here is an example:

IDENTIFICATION DIVISION.
PROGRAM-ID. CALLER.
DATA DIVISION.
WORKING-STORAGE SECTION.

01 MYSUB-CONTROL.
    03   MYSUB-ACTION-SWITCH          PIC X.
         88 MYSUB-ACTION-EVALUATE             VALUE "E".
         88 MYSUB-ACTION-SET-AND-EVALUATE     VALUE "S".
    03   MSG-TEXT                     PIC X(20).
    03   MSG-SIZE                     PIC 9(8).

01 TEXT-STRING                   PIC X(20).

PROCEDURE DIVISION.
START-PROGRAM SECTION.
START-PROGRAM-S.
*   Set ACTION-SWITCH to the function required (set and evaluate).
     MOVE "S" TO MYSUB-ACTION-SWITCH.
*   Prepare the text parameter to this subroutine
     MOVE "ANYTEXT" TO TEXT-STRING.
*   Call the subroutine to perform this function
     CALL "MYSUB" USING MYSUB-CONTROL, TEXT-STRING.

  DISPLAY "MSG-TEXT: ", MSG-TEXT,
             "MSG-SIZE: ", MSG-SIZE.

  EXIT-PROGRAM.
      EXIT PROGRAM.

      STOP RUN.

Image

You may have noticed that you separate MYSUB’s parameters into two types: items in the CONTROL-AREA and other parameter items. This is done by design in order to distinguish parameters in the CONTROL-AREA (these are analogous to class data members) and other parameters (analogous to parameters passed to a class’s methods, or functions). You will expand on this convention as you go.

MESSAGES IN JAVA

Once again, let’s compare what you’ve done in COBOL to the way you would do it in Java.

ERRORMSG CLASS

Let’s define a method in the ErrorMsg class.

public class ErrorMsg {

     public String msgText;
     public int msgSize;

     public void setErrorMsg (String inputMsg) {
          ...
 // Some logic
         ...
         ;
     }
}

The statement that contains setErrorMsg describes a public entry point (i.e., a method) to the class ErrorMsg. These methods can be called by other classes to perform some function in this class.

Image

The statement could be read this way: “Define a public method for class ErrorMsg. This method returns no data (void) and its name is setErrorMsg. This method accepts one parameter of type String; the parameter’s name as used by the class is inputMsg.”

CALLER CLASS

A consumer (calling) class can use this method in the following way:

// Create a new object of type ErrorMsg.
     ErrorMsg     myErrorMsg = new     ErrorMsg ();
     ...
// Call the method in the object called setErrorMsg.

Image

This statement calls the object’s method and requests that it perform some behavior based on the passed parameter. Sometimes this is described as sending a message to that object.

MULTIPLE MESSAGES

Classes can easily support more than one message definition or even variations on a single message. In fact, it is this easy-to-use message specification that helps distinguish OO languages from their more procedural cousins.

CLASS ERRORMSG

Let’s look at some examples that show how a class publishes the types of messages it can receive using Java’s syntax.

      public class ErrorMsg {

           public String msgText;
           public int msgSize;

(1)           public void setErrorMsg (String inputMsg) {
                   ...
           // Some logic
                   ...
// The method is complete. Return to the caller.
                  return;
             }

(2)          public String getErrorMsg () {
                   ...
           // Some logic
                   ...
// The method is complete.
// Return a String variable as the result (or return argument) of this
// method.
                  return (returnMsg);
             }

(3)          public String getErrorMsg (int msgCode) {
                 ...
         // Some logic
                 ...
                 return (returnMsg);
             }
         }

The new message definition statements (2 and 3) could be read this way: “Define a public method for class ErrorMsg. This method returns a String data item, and the method’s name is getErrorMsg. One form of this method accepts no parameters (statement 2), and another form accepts one parameter of type int (statement 3).”

The method getErrorMsg defines other functions that ErrorMsg can support. As such, these are additional components of the interface to ErrorMsg. These methods can access any of ErrorMsg’s data items or methods (both public and private ones). Since the methods are themselves public, any class can call these methods.

Notice that the methods named getErrorMsg have different signatures (interface definitions) than the setErrorMsg method. They do not have a String input parameter, but they do return a String variable.

Notice also that the method getErrorMsg is defined twice in ErrorMsg. The first method specification accepts no parameters, and the second accepts one parameter of type int. This parameter’s name (as used internally by the method) is msgCode.

METHOD OVERLOADING

Having two variations on the same method is an example of method overloading. This is another mechanism to request a specific function in the class ErrorMsg. Methods with the same name can be defined to require variable numbers or different types of parameters. Consumer (calling) classes can request any of these public methods. The compiler will examine a method call, including its input parameters and return type, and call the correct public method of the class.

CALLER CLASS

After the ErrorMsg class has been properly compiled, a consumer class can use these various methods in the following way:

Image

METHOD OVERLOADING IN COBOL

There is no direct analogy to method overloading in COBOL, but there is a coding technique that is pretty close. COBOL compilers will generally let you call a subroutine and pass fewer parameters than specified in the USING statement. Suppose you designed a subroutine where some actions performed by the subroutine might require two parameters, and other actions might require three. Calling programs can pass either two or three parameters but would be responsible for passing the correct number of parameters, based on the action requested. It would then be the responsibility of the subroutine to make sure that no missing parameters are accessed by the subroutine during this particular call. Parameters that have been passed can be accessed by the subroutine, but the subroutine designer must be careful not to perform any statement that accesses an item defined in LINKAGE SECTION but not passed by the caller. In fact, some compilers support this technique explicitly by providing a mechanism to detect (at runtime) the number of passed parameters. In some systems, you may have to call an Assembler program to detect the number of parameters.

MYSUB COBOL

This example manages different numbers of parameters. It uses the “GET$NARGS” function as provided by the AcuCorp COBOL compiler.

IDENTIFICATION DIVISION.
PROGRAM-ID. MYSUB.
************************************************************************
* This routine accepts a text item as a parameter and                  *
* evaluates the text. If the text is all spaces,                       *
* MSG-SIZE will be set to 0. Else, MSG-SIZE                            *
* will be set to 1.                                                    *
* If requested, the text item will also be stored in the               *
* passed control structure.                                            *
* If the text item is not passed, then MSG-TEXT                        *
* will be evaluated instead.                                           *
************************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.

01 ARGUMENT-COUNT             PIC 9.
01 LOCAL-TEXT                 PIC X(20).

LINKAGE SECTION.
01 MYSUB-CONTROL.
    03   MYSUB-ACTION-SWITCH     PIC X.
         88 MYSUB-ACTION-EVALUATE           VALUE "E".
         88 MYSUB-ACTION-SET-AND-EVALUATE    VALUE "S".
    03   MSG-TEXT                PIC X(20).
    03   MSG-SIZE                PIC 9(8).

01 TEXT-STRING              PIC X(20).

PROCEDURE DIVISION USING MYSUB-CONTROL, TEXT-STRING.

MYSUB-INITIAL SECTION.
MYSUB-INITIAL-S.
*   Perform some function to detect the number of arguments.
     PERFORM GET-ARGUMENT-COUNT.
*   Determine whether TEXT-STRING or MSG-TEXT should be evaluated.
Store
  the correct item in LOCAL-TEXT.
     IF ARGUMENT-COUNT = 2
          MOVE TEXT-STRING TO LOCAL-TEXT
     ELSE
          MOVE MSG-TEXT TO LOCAL-TEXT.
*   Now, use LOCAL-TEXT in the subroutine's logic.
    IF LOCAL-TEXT = SPACES
          MOVE 0 TO MSG-SIZE
     ELSE
          MOVE 1 TO MSG-SIZE.

     IF MYSUB-ACTION-SET-AND-EVALUATE
          MOVE LOCAL-TEXT TO MSG-TEXT.

 EXIT-PROGRAM.
     EXIT PROGRAM.

 GET-ARGUMENT-COUNT SECTION.
 GET-ARGUMENT-COUNT-S.
*   Set ARGUMENT-COUNT to the result.
    CALL "GET$NARGS" USING ARGUMENT-COUNT.

In this example, there are really two interfaces defined for MYSUB, one with a single parameter and another with two parameters. Calling programs can use either interface, depending on their requirements.

CALLER COBOL

Now, CALLER can pass one or two parameters.

IDENTIFICATION DIVISION.
PROGRAM-ID. CALLER.
DATA DIVISION.
WORKING-STORAGE SECTION.

01 MYSUB-CONTROL.
    03   MYSUB-ACTION-SWITCH    PIC X.
         88 MYSUB-ACTION-EVALUATE         VALUE "E".
         88 MYSUB-ACTION-SET-AND-EVALUATE VALUE "S".
    03   MSG-TEXT               PIC X(20).
    03   MSG-SIZE               PIC 9(8).

01 TEXT-STRING             PIC X(20).
...
PROCEDURE DIVISION.
START-PROGRAM SECTION.
START-PROGRAM-S.
*   Set ACTION-SWITCH to the function required (set and evaluate).
     MOVE "S" TO MYSUB-ACTION-SWITCH.
*   Clear the two MYSUB control items, to make sure you see the result.
     MOVE SPACES TO MYSUB-TEXT.
     MOVE ZEROS TO MYSUB-SIZE.
*   Call MYSUB with two parameters.
     MOVE "ANYTEXT" TO TEXT-STRING.
     CALL "MYSUB" USING MYSUB-CONTROL, TEXT-STRING.
     DISPLAY "MSG-TEXT: ", MSG-TEXT,
            " MSG-SIZE: ", MSG-SIZE.
*   Set ACTION-SWITCH to the function required (evaluate only).
     MOVE "E" TO MYSUB-ACTION-SWITCH.
*   Clear the two MYSUB control items, so you are sure to see the *
*   result.
     MOVE SPACES TO MYSUB-TEXT.
     MOVE ZEROS TO MYSUB-SIZE.
*   Call MYSUB, passing only one parameter.
*         The stored string in MSG-TEXT will be evaluated.
     CALL "MYSUB" USING MYSUB-CONTROL.
     DISPLAY "MSG-TEXT: ", MSG-TEXT,
            " MSG-SIZE: ", MSG-SIZE.
*   Try it with some text in MSG-TEXT.
     MOVE "Some Text" TO MYSUB-TEXT.
     MOVE ZEROS    TO MYSUB-SIZE.
*   Call MYSUB, passing only one parameter.
*   The stored string in MSG-TEXT will be evaluated.
     CALL "MYSUB" USING MYSUB-CONTROL.

     DISPLAY "MSG-TEXT: ", MSG-TEXT,
            " MSG-SIZE: ", MSG-SIZE.

EXIT-PROGRAM.
    EXIT PROGRAM.
    STOP RUN.

I have demonstrated how a developer can support multiple interfaces to a single COBOL subroutine. This avoids the problem of having to write and support two separate yet similar routines; a single routine can perform both roles. However, care must be exercised in both building and using the routine to make sure that the proper interface is being used at the proper time. A calling program can easily cause a runtime error by requesting one type of interface but not passing the proper number of parameters.

Java’s compiler and runtime system support this technique more explicitly and with much more functionality. The developer does not need to worry about which interface will be called and which parameter(s) may or may not be available; instead, the compiler automatically takes care of these details.

Image

Remember the distinctions that have made between MYSUB’s CONTROL-AREA and the other parameters passed to MYSUB? In these examples, every call to MYSUB must pass the CONTROL-AREA, regardless of the other parameters passed. Only the other parameters are optional.

This is similar to the way Java distinguishes between member data items and passed parameters. Class member items are always available, regardless of the interface used. For example, one method may require a single integer parameter and return a String data type, whereas another accepts no parameters and does not return a data type (i.e., its return type is void). However, both of these methods can access any of the class members, both the public and the private ones. The caller, on the other hand, can access only the public class members, either before or after performing the method.

Let’s return, for a moment, to the Java example. This call to the method getErrorMsg (by the CALLER) will always perform the method in ErrorMsg that accepts no parameter and returns a String result:

      myString = myErrorMsg.getErrorMsg ();

(1)                  public String getErrorMsg () {...}

On the other hand, this call to getErrorMsg will always perform the method that accepts one integer parameter and returns a String result:

      myString = myErrorMsg.getErrorMsg (msgCode);

(2)                  public String getErrorMsg (int msgCode) {...}

The Java compiler will automatically match up the particulars of the method invocation (in CALLER) with the particulars of the method (in ErrorMsg), and make sure the proper method is executed.

TERMS TO REVIEW

Let’s review some of the object-oriented concepts just discussed and how you can understand them from a Java perspective.

Methods: Methods are the functions that a class can perform. Performing a method is similar to calling a function, or sending a message (to an object).

Method signatures: The method signatures of a class are the view it presents to external programs. A class can have many public methods. Each method can be further qualified by its method name, arguments, return type, and scope (e.g., public, protected, private). This combination of unique method name, argument profile, and return value is sometimes referred to as an interface in OO design terms. Note that the term interface is formally reserved for a specific construct in the Java language.

Method overloading: A class can define a method and then create more than one signature for this method. These unique interfaces are distinguished by their input parameters and return type.

EXERCISES: CLASSES, OBJECTS, AND METHODS

It’s useful to use the keyboard and—as a good piano teacher might say—let your fingers teach your mind. You’ll experiment with some of the sample classes presented so far.

Create an ErrorMsg class:

  1. Using a text editor, create a Java source file named ErrorMsg.java in the java4cobol directory. The source file should contain these statements:

    public class ErrorMsg {
    // Define some public class instance variables.
              public String msgText = " ";
              public int    msgSize;
    // Define a public method.
              public void setErrorMsg (String inputMsg) {
    // Modify one of the public variables. Set this variable to the text
    // String that was passed as a parameter.
                   msgText = inputMsg;
    // Return from this method. Since this method has no return value (i.e.,
    // it is declared as void), no return statement is necessary.
         }
    // Define another public method.
              public String getErrorMsg () {
                  String returnMsg;
    // Set the local variable returnMsg to the data member msgText.
                   returnMsg = msgText;
    // Return from this method, and return this String variable.
                   return (returnMsg);
              }

    }

    Remember to save this source as a text file instead of a document file. The file name should be c:java4cobolErrorMsg.java.

  2. In the DOS command window, change the current directory to your java4cobol directory:

    →   cd c:java4cobol

  3. Compile your class, using the javac compiler:

    →   javac ErrorMsg.java

    Again, your class should compile successfully at this point. If it doesn’t, review the suggestions mentioned in the introductory SDK exercises.

  4. Using a text editor, modify and compile your HelloWorld.java source file in the java4cobol directory. The source file should contain these statements:

    public class HelloWorld
    {
         public static void main(String args[])
         {
              String tempMsg;
    // Our original println statement:
              System.out.println("Hello World!");
    // Create a new instance of the ErrorMsg class:
              ErrorMsg myErrorMsg = new ErrorMsg ();
    // Get the value of the text item in ErrorMsg, by calling the getErrorMsg
    // method.
              tempMsg = myErrorMsg.getErrorMsg ();
    // Print the contents of the String returned by this method.
              System.out.println (tempMsg);
    // Set the text item in ErrorMsg to some text String, and print its // //
    // contents.
              myErrorMsg.setErrorMsg ("Some Text");
              tempMsg = myErrorMsg.getErrorMsg ();
              System.out.println (tempMsg);
    // Call the setErrorMsg method again to set ErrorMsg to some other text.
              myErrorMsg.setErrorMsg ("Some New Text");
              tempMsg = myErrorMsg.getErrorMsg ();
              System.out.println (tempMsg);

         }

    }

  5. Now run your program, using the Java runtime that comes with the SDK:

    →   java HelloWorld

    If you’ve done everything correctly, your MS-DOS window should look like this:

    C:>javac ErrorMsg.java

    C:>javac HelloWorld.java

    C:>java HelloWorld

    Hello World!

    Some Text
    Some New Text

    C:java4cobol>

  6. Experiment with this program. Add the following lines to the end of your HelloWorld.java source file (i.e., immediately after the last println statement):

    // Create a new instance of the ErrorMsg class.
              ErrorMsg myErrorMsg2 = new ErrorMsg ();
    // Set the text item to some text String, and print its contents.
              myErrorMsg2.setErrorMsg ("Some Text for #2");
              tempMsg = myErrorMsg2.getErrorMsg ();
              System.out.println (tempMsg);
    // Print the text item in the original object.
              tempMsg = myErrorMsg.getErrorMsg ();
              System.out.println (tempMsg);

  7. Save the program again. Compile and execute it by performing these statements in the command window:

    →   javac HelloWorld.java

    →   java HelloWorld

    Your DOS window should look like this:

    C:>javac HelloWorld.java

    C:>java HelloWorld
    Hello World!

    Some Text
    Some New Text
    Some Text for #2
    Some New Text


    C:java4cobol>

The ErrorMsg class has two methods defined for it: setErrorMsg and getErrorMsg. You can define a variation on getErrorMsg. This alternative, or overloaded method, will convert the returned String to all uppercase letters.

  1. Using a text editor, edit the Java source file ErrorMsg.java in the java4cobol directory.

  2. Add the following lines to the end of your ErrorMsg.java source file (i.e., immediately before the last brace (}) in the class):

    // Define a variation on the public method getErrorMsg.
              public String getErrorMsg (char caseFlag) {
                  String returnMsg;
    // Set the local variable returnMsg to the data member msgText.
                   returnMsg = msgText;
    // Convert to all uppercase, if requested.
                   if (caseFlag == 'U')
                        returnMsg = returnMsg.toUpperCase ();
    // Return from this method, and return the String variable.
                   return (returnMsg);
              }

  3. Compile the class again in the DOS command window:

    →   javac ErrorMsg.java

  4. Modify HelloWorld to use this new method. Using a text editor, edit the Java source file HelloWorld.java in the java4cobol directory.

  5. Add the following lines to the end of your HelloWorld.java source file (i.e., immediately after the last println statement):

    // Call the new variation of the getErrorMsg method.
    // This variation will return an all uppercase message.
              tempMsg = myErrorMsg.getErrorMsg ('U'),
              System.out.println (tempMsg);

  6. Compile and execute the program again in the DOS command window:

    →   javac HelloWorld.java

    →   java HelloWorld

    Your output window should contain these lines:

    C:>javac ErrorMsg.java

    C:>javac HelloWorld.java

    C:>java HelloWorld
    Hello World!

    Some Text
    Some New Text
    Some Text for #2
    Some New Text
    SOME NEW TEXT


    C:java4cobol>

You will now modify the applet version of your HelloWorld class so that it also uses the ErrorMsg class.

  1. Using the text editor, edit the HelloWorld.java file in your java4cobol applet directory.

  2. Add the required source text to your HelloWorld applet class so that it looks like this:

    import java.applet.Applet;
    import java.awt.Graphics;

    public class HelloWorld extends Applet
    {

         public void paint(Graphics g)
         {
              String tempMsg;


              g.drawString("Hello applet World!", 5, 25);
    // Create a new instance of the ErrorMsg class.
              ErrorMsg myErrorMsg = new ErrorMsg ();
    // Print the contents of the public data member msgText in our class.
              tempMsg = myErrorMsg.getErrorMsg ();
              g.drawString (tempMsg, 5, 35);
    // Set msgText to some text String, and print its contents.
              myErrorMsg.setErrorMsg ("Some Text");
              tempMsg = myErrorMsg.getErrorMsg ();
              g.drawString (tempMsg, 5, 45);
    // Call the setErrorMsg method to set the text to some other text, and
    // print its contents.
              myErrorMsg.setErrorMsg ("Some New Text");
              tempMsg = myErrorMsg.getErrorMsg ();
              g.drawString (tempMsg, 5, 55);

         }


    }

  3. Save the source file in text format. The file name should be c:java4cobol appletHelloWorld.java.

  4. Compile the program after changing to the applet directory in your DOS window.

    →   cd c:java4cobolApplet

    →   javac HelloWorld.java

    What happens? Did you get an error message that looked like this?

    C:>cd applet

    C:>javac HelloWorld.java
    HelloWorld.java:13: Class ErrorMsg not found.
               ErrorMsg myErrorMsg = new ErrorMsg ();
               ^
    HelloWorld.java:13: Class ErrorMsg not found.
               ErrorMsg myErrorMsg = new ErrorMsg ();
                                         ^
    2 errors

    C:java4cobolapplet>

What is the proper solution for this error? Should you create a new class called ErrorMsg as part of this project? Or should you use the ErrorMsg class that you had previously created?

If you chose the first solution, go to the rear of the class. If you chose the second, congratulations! You are well on your way to becoming an object-oriented programmer! The primary objective when you create a class is to have other programs reuse that class. This objective is not met when a class is copied, so make sure to always resist that temptation.

The SDK Java development environment can use a variety of mechanisms to find the proper class files. You will cover them all eventually, but the simplest one to use right now is the CLASSPATH argument. This argument lists directory names the Java compiler should search in order to find any required classes.

  1. Tell the Java compiler where the ErrorMsg class is by adding the CLASS-PATH argument to the java compile statement in your command window:

    →   javac -classpath c:java4cobol HelloWorld.java

    It should compile successfully now.

  2. Now run your new HelloWorld applet. You will need to set the CLASS-PATH argument when you run it as follows:

    →   appletviewer -J-classpath -J.;c:/java4cobol HelloWorld.html

    Image

    The syntax for the classpath includes an initial period, followed by a semicolon. This tells the appletviewer to search in the current directory “.” and then in the c:java4cobol directory for all classes.

    Experiment with this applet as well. You can make the changes in the text editor and then recompile the applet in the command window.

  3. Add the following lines to the end of your HelloWorld.java source file (i.e., immediately after the last g.drawString statement).

    // Create a new instance of the ErrorMsg class.
              ErrorMsg myErrorMsg2 = new ErrorMsg ();
    // Set the text item to some text String, and print its contents.
              myErrorMsg2.setErrorMsg ("Some Text for #2");
              tempMsg = myErrorMsg2.getErrorMsg ();
              g.drawString (tempMsg, 5, 75);
    // Print the text item in the original object.
              tempMsg = myErrorMsg.getErrorMsg ();
              g.drawString (tempMsg, 5, 85);

  4. Save the program again. Compile and execute it by performing these statements in the command window:

    →   javac -classpath c:java4cobol HelloWorld.java

    →   appletviewer -J-classpath -J.;c:/java4cobol HelloWorld.html

    Your applet window should look like this:

    Hello applet World!

    Some Text
    Some New Text

    Some Text for #2
    Some New Text

    Image

    The appletviewer that comes with SDK does not print null as the way to represent an uninitialized String; instead, it generates an exception, or error condition. Therefore, the ErrorMsg class (as defined for the exercises) initializes its data member named msgText to a single space.

  5. Now, have the applet use the overloaded version of getErrorMsg. Add the following lines to the end of yourHelloWorld.java source file (i.e., immediately after the last g.drawString statement):

    // Call the new variation of the getErrorMsg method.
    // This variation will return an all uppercase message.
              tempMsg = myErrorMsg.getErrorMsg ('U'),
              g.drawString (tempMsg, 5, 95);

  6. Save the program again. Compile and execute it by performing these statements in the command window:

    →   javac -classpath c:java4cobol HelloWorld.java

    →   appletviewer -J-classpath -J.;c:/java4cobol HelloWorld.html

    Your applet window should look like this:

    Hello applet World!

    Some Text
    Some New Text

    Some Text for #2
    Some New Text
    SOME NEW TEXT

REVIEWING THE SAMPLES

Let’s review the class you’ve created (ErrorMsg) and the main program that uses it (HelloWorld). Try to relate the sample source statements to the result (for example, the output) each statement creates. If necessary, rerun the samples or look at the complete source code at the end of this section. Feel free to experiment by yourself.

  • ErrorMsg is the first example of a reusable class. Your first program, Hello-World, was a standalone application. ErrorMsg, on the other hand, is a class that HelloWorld can use. The original HelloWorld program from the first set of exercises was modified to use this class.

  • HelloWorld first creates a new instance of ErrorMsg with this statement:

    ErrorMsg myErrorMsg = new ErrorMsg ();

  • To confirm that an instance has been created, HelloWorld prints out the contents of one of ErrorMsg’s public data members. The default value for a String data type is null. The ErrorMsg class as defined in the example in the first path of this chapter does not specify any initial data. Therefore, these statements

    System.out.println ("HelloWorld!");
    tempMsg = myErrorMsg.getErrorMsg ();
    System.out.println (tempMsg);

    would produce

    Hello World!
    null

  • This println statement causes the text null to appear in the output window.

  • On the other hand, the version of ErrorMsg in the exercises initialized the msgText data member to one space. Therefore, these statements

        System.out.println ("HelloWorld!");
        tempMsg = myErrorMsg.getErrorMsg ();
        System.out.println (tempMsg);
    Hello World!

    cause a single space character to appear in the output window (which is invisible).

  • The HelloWorld application then stores some text, in this instance, of ErrorMsg. HelloWorld uses the setErrorMsg method to store this text.

    myErrorMsg.setErrorMsg ("Some Text");

  • HelloWorld next gets the text item from ErrorMsg and prints out the contents of this data member. Note that the output for this statement is the text “Some Text.”

          tempMsg = myErrorMsg.getErrorMsg ();
          System.out.println (tempMsg);
    Some Text

  • Next, HelloWorld modifies the data member and prints out its new contents. In this case, the output for this print statement is the text “Some New Text.”

          myErrorMsg.setErrorMsg ("Some New Text");
          tempMsg = myErrorMsg.getErrorMsg ();
          System.out.println (tempMsg);
    Some New Text

  • Finally, you modified HelloWorld to create a second instance of ErrorMsg and stored a reference to this new instance in the variable myErrorMsg2. You then stored the String “Some Text for #2” in its data member, using the setErrorMsg method:

          ErrorMsg myErrorMsg2 = new ErrorMsg ();
          myErrorMsg2.setErrorMsg ("Some Text for #2");
          tempMsg = myErrorMsg2.getErrorMsg ();
          System.out.println (tempMsg);
    Some New Text for #2

  • To show that two unique objects of the same type exist in HelloWorld, you printed out the data contained in both objects. The data associated with myErrorMsg2 contained “Some Text for #2,” and the data associated with myErrorMsg contained “Some New Text.”

         tempMsg = myErrorMsg2.getErrorMsg ();
         System.out.println (tempMsg);
         tempMsg = myErrorMsg.getErrorMsg ();
         System.out.println (tempMsg);
    Some New Text for #2
    Some New Text

  • The applet versions of HelloWorld performed much the same as did the application versions. HelloWorld, the applet, created an instance of ErrorMsg, stored some text in it, and then printed the text. Instead of printing to standard out, you used the Graphics class to print to a graphical window:

         System.out.println (tempMsg);          » becomes «
         g.drawString (tempMsg, 5, 35);
    Hello applet World!

In the SDK applet exercise, this drawString statement causes no data to be displayed.

  • You were able to simply use the existing version of ErrorMsg in the applets. That is, you did not need to create two versions of ErrorMsg, one for the application and one for the applet.

  • You did need to instruct the compile environment where to look for the ErrorMsg class when it was not part of the current directory. You used the CLASSPATH argument (or project setting) to inform the compile environment of the directory that contained ErrorMsg.class.

  • In the case of the SDK, you also needed to inform the execution environment (APPLETVIEWER.EXE) where it should look for the ErrorMsg class.

  • As you did with the application HelloWorld, the applet was extended to contain two instances of ErrorMsg, each with its own data members:

    ErrorMsg myErrorMsg2 = new ErrorMsg ();
    myErrorMsg2.setErrorMsg ("Some Text for #2");

  • To show that two unique data members with the same name exist in Hello-World (one for each object of type ErrorMsg), you displayed both data members. The one associated with myErrorMsg2 contained “Some Text for #2,” and the one associated with myErrorMsg contained “Some Text.”

    tempMsg = myErrorMsg2.getErrorMsg ();
    g.drawString (tempMsg, 5, 75);
    tempMsg = myErrorMsg.getErrorMsg ();
    g.drawString (tempMsg, 5, 85);

  • Finally, you showed how ErrorMsg could define two variations on the same method. This is known as method overloading. The new variation accepted one character argument and is the argument that was set to the character value 'U' that represents the case flag to tell the method to convert the return message to all uppercase.

    // Define a variation on the public method getErrorMsg.
              public String getErrorMsg (char caseFlag) {
                   String returnMsg;
    // Set the local variable returnMsg to the data member msgText.
                   returnMsg = msgText;
    //  Define a variation on the public method getErrorMsg.
    //  Perform the standard 'getErrorMsg' method.
              public String getErrorMsg (char caseFlag) {

    //  Convert to all upper case, if requested.
                   if (caseFlag == 'U')
                        return (getErrorMsg().toUpperCase ());
                   else

    //  Return from this method, without conversion.
                        return (getErrorMsg());

HelloWorld can use this new method to request a return message that is all uppercase.

          tempMsg = myErrorMsg.getErrorMsg ('U'),
          System.out.println (tempMsg);
Hello applet World!

Some Text
Some New Text

Some Text for #2
Some New Text
SOME NEW TEXT

HELLOWORLD: THE APPLICATION

public class HelloWorld {
     public static void main(String args[]) {
          String tempMsg;
// Our original println statement:
          System.out.println("Hello World!");
// Create a new instance of the ErrorMsg class.
     ErrorMsg myErrorMsg = new ErrorMsg ();
// Get the value of the text item in ErrorMsg by calling the
// getErrorMsg method.
          tempMsg = myErrorMsg.getErrorMsg ();
// Print the contents of the String returned by this method.
          System.out.println (tempMsg);
// Set the text item in ErrorMsg to some text String, and print its
// contents:
          myErrorMsg.setErrorMsg ("Some Text");
          tempMsg = myErrorMsg.getErrorMsg ();
          System.out.println (tempMsg);
// Call the setErrorMsg method again to setErrorMsg to some other text.
          myErrorMsg.setErrorMsg ("Some New Text");
          tempMsg = myErrorMsg.getErrorMsg ();
          System.out.println (tempMsg);
// Create a new instance of the ErrorMsg class.
          ErrorMsg myErrorMsg2 = new ErrorMsg ();
// Set the text item to some text String, and print its contents.
          myErrorMsg2.setErrorMsg ("Some Text for #2");
          tempMsg = myErrorMsg2.getErrorMsg ();
          System.out.println (tempMsg);
// Print the text item in the original object.
          tempMsg = myErrorMsg.getErrorMsg ();
          System.out.println (tempMsg);
// Call the new variation of the getErrorMsg method.
//  This variation will return an all uppercase message.
          tempMsg = myErrorMsg.getErrorMsg ('U'),
          System.out.println (tempMsg);

     }
}

HELLOWORLD: THE APPLET

import java.applet.Applet;
import java.awt.Graphics;

public class HelloWorld extends Applet {

     public void paint(Graphics g) {
          String tempMsg;
          g.drawString("Hello applet World!", 5, 25);
// Create a new instance of the ErrorMsg class.
          ErrorMsg myErrorMsg = new ErrorMsg ();
// Print the contents of the public data member msgText in the class.
          tempMsg = myErrorMsg.getErrorMsg ();
          g.drawString (tempMsg, 5, 35);
// Set msgText to some text String, and print its contents.
          myErrorMsg.setErrorMsg ("Some Text");
          tempMsg = myErrorMsg.getErrorMsg ();
          g.drawString (tempMsg, 5, 45);
// Call the setErrorMsg method to set the text to some other text, and
// print its contents.
          myErrorMsg.setErrorMsg ("Some New Text");
          tempMsg = myErrorMsg.getErrorMsg ();
          g.drawString (tempMsg, 5, 55);

// Create a new instance of the ErrorMsg class.
          ErrorMsg myErrorMsg2 = new ErrorMsg ();
// Set the text item to some text String, and print its contents.
          myErrorMsg2.setErrorMsg ("Some Text for #2");
          tempMsg = myErrorMsg2.getErrorMsg ();
          g.drawString (tempMsg, 5, 75);
// Print the text item in the original object.
          tempMsg = myErrorMsg.getErrorMsg ();
          g.drawString (tempMsg, 5, 85);
// Call the new variation of the getErrorMsg method.
// This variation will return an uppercase message.
          tempMsg = myErrorMsg.getErrorMsg ('U'),
          g.drawString (tempMsg, 5, 95);

     }
}

ERRORMSG: THE CLASS

public class ErrorMsg {
// Define some public class instance variables.
          public String msgText = " ";
          public int msgSize;
// Define a public method.
          public void setErrorMsg (String inputMsg) {
// Modify one of the public variables. Set this variable to the text
// String that was passed as a parameter.
               msgText = inputMsg;
// Return from this method. Since this method has no return value
// (i.e., it is declared as void), no return statement is necessary.
          }
// Define another public method.
          public String getErrorMsg () {
              String returnMsg;
// Set the local variable returnMsg to the data member msgText.
               returnMsg = msgText;
// Return from this method, and return this String variable.
               return (returnMsg);
          }
// Define a variation on the public method getErrorMsg.
          public String getErrorMsg (char caseFlag) {
              String returnMsg;
// Set the local variable returnMsg to the data member msgText.
               returnMsg = msgText;
// Convert to all uppercase, if requested.
               if (caseFlag == 'U')
                    returnMsg = returnMsg.toUpperCase ();
// Return from this method, and return the String variable.
               return (returnMsg);
          }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset