Chapter 7

Introduction to Java

by Dan Joshi


CONTENTS

A class is Java's name for an object in the object-oriented paradigm. One of the first things you should learn is how to use Java classes. This is a logical first step because everything in Java is done through the use of classes. A major stumbling block arises for new object-oriented programmers when they try to understand the control flow stuff first and then try to apply it by writing programs. The resulting programs have major problems because of Java's reliance on objects.

Later, you will examine Java's structured environment before going on to more advanced object-oriented topics, but first your foundation should start with the basics learning objects and classes. In short, a class is the formal representation for an object in Java.

Classes, Methods, Inheritance, and Method Overriding-The Discussion

This section (as with all sections that have "The Discussion" in their headings) is designed to give you a theoretical understanding of objects, object inheritance, and method overriding. The next section gives you a workshop dealing with what was presented in this section.

Your goal in this section is to build an understanding, so don't try to compile any of the examples in the first section-they will compile but won't have the functionality to help you understand the concepts being taught in this section.

Classes

The following is an example of how a class would be declared in Java:


class Book {



}

The keyword class indicates that this is a declaration for a Java class. Classes are how Java houses objects. The brackets designate a space known as a block. Any code that you want to relate to the class of Book is put in that block. This is the fundamental object-oriented logic that you will use to organize all your programs. Even without putting code between the brackets, the brackets are still necessary operators.

Now add a variable that is related to your newly created class Book:


class Book {

   int NumberofPages;

}

The preceding code shows one format in which you can declare a variable. The int in front of the word NumberofPages tells Java that the variable NumberofPages is going to an integer of the integer data type.

Variables will be formally discussed later in the chapter, but right now let's just focus on the semicolon at the end of the declaration in that statement. One common minor mistake that programmers make is not using the semicolon to terminate the above statement. Without the semicolon, Java will give you an error message. Usually Java's compiler will catch the omission and tell you that it anticipates a semicolon where it did not find one; but sometimes it can give you 10 error messages when really only one semicolon was missing. Make a note to yourself, if you are new to semicolon languages, to make sure all the semicolons are where they belong.

Methods

A method is object-oriented terminology for a function. A function is an algorithm that can take an input, manipulate it, and return an output. The major difference between methods and functions is that a method is a function that belongs to a class.

NOTE
C++ programmers should note that Java does not support stand-alone methods.

The only way to employ a method is to wrap it inside a class. To avoid any confusion, the following example shows just a method declaration that is not wrapped in any class:


void open() {



   // algorithm to handle the method.



}

First, notice the word void in front of the word open(). That word void represents the place where a return type is designated for this method-just as a function (that is, an algorithm) can have a return type. Basically, when declaring a method, you use that place to declare what type of data will be returned. In this case you are using void, which means that no information will be returned from this method.

Second, notice the parentheses after the name open. This is where you can place input variables for the method. The name open() in this form means that you need no input variables to process the method. Once again notice that, even though you do not have an input variable yet, you still must put the parentheses around the method name. That is because the parentheses around the method are operators just as the brackets were operators in the earlier example of a class declaration.

The following is an example of another method-it has a return type of integer and two input integer variables that are declared values as well:


int AddTwoNumbers(int FirstNumber, int SecondNumber)  {

   return FirstNumber + SecondNumber;

}

NOTE
To understand what an operator does, think of a doctor (who is the operator) operating on the patients (who are the operands), producing a result.

First, notice the int before the AddTwoNumbers. That means the method will return an integer value. As you can see in the block code inside the method, you have the statement return just before the calculation. The keyword return is the method's cue to return the value of the expression immediately following it.

Going back to the first method open(), you know that Java does not support methods that are not attached to a class; so let's see how you would add open() to the class of Book:


class Book {

   int NumberofPages;



   void open() {

      // algorithm to handle the method.

   }

}

Inheritance

The next step in this lesson is to create a subclass. An important thing to understand here is how to build a subclass to extend the current class Book. Recalling the explanation of subclasses and superclasses in Chapter 5 "Java and the Internet," you will create a class named paperback. Logically, you know that not all books are paperbacks, but all paperbacks (pamphlets, leaflets, and so on excluded) are books. When you have understood the logic behind that statement, you will have mastered the relationship among classes that a programmer creates when using inheritance.

The following statement is in the object model of the Java programming language. In it you have created a new class called paperback. This class has its own variables and methods; but in addition, it has all the functionality (the methods and variables) of the class Book, as well.


class paperback extends Book {



   string NameofBook;



}

Looking at the preceding code, notice that the extends keyword is used to perform inheritance between the subclass paperback and the superclass Book.

There is a way, however, to prevent some variables and methods from being passed on or inherited to any other classes; that is by using the keyword private before the opening statement or declaration. Later, you will see an official definition of the keyword private and related access modifiers; but for now, to learn its use, you will create another class called HardCoverBook:


class HardCoverBook extends Book {



   private int EndingToTheStory;

}

As you can see in the preceding example, the keyword private is located before the type declaration. This position is important because it ensures that the variable will be available only to this class. The following example is a declaration for a class called ThickHardCoverBook. It is a subclass to HardCoverBook:


class ThickHardCoverBook extends HardCoverBook {



}

This class will not have access to the variable EndingToTheStory. Access modifiers define the accessibility of the variable or method in their own class as they relate to other classes. In the preceding example, private is just one of several access modifiers.

The following list shows all of the access modifiers with the most restrictive at the top:

privateWhen this is placed in front of a method or variable, that method or variable will be accessible only to the class in which it was originally declared.
protectedWhen this is placed in front of a method or variable, that method or variable will be accessible to the class it was declared in and any subclasses inherited from it.
friendlyThis is the assumed state for a method or variable-it is what you declare a variable to be when you put nothing in front of it. Any of the classes in the package have access to it.
publicThis access modifier is the least restrictive-it makes the method or variable accessible to everything.
finalThis access modifier means that the current method or variable cannot be extended.
synchronizedThis is a modifier that will lock the object while it is being used. If the method or variable is already locked, the program would wait until the method or variable becomes available before having access to it. This is useful when your program deals with multiple threads.

NOTE
A package is a group of related classes.

Method Overriding

Java supports method overriding. Method overriding is basically replacing a method in the superclass with a method from a subclass. Here is an example of method overriding in the class Book:


class Book {



   int NumberofPages;



   void open() {

      // algorithm to handle the method.

   }

}

Now recall the inherited class paperback:


class paperback extends Book {



   string NameofBook;



   void open() {

      // a special algorithm specific to the class paperback.

   }

}

The class paperback extends Book. Remember that the same declaration for the open() method resides in paperback. The open() method in Book is now completely hidden from this class and is replaced with the implementation code of the open() method in paperback.

An easy way to think of overriding methods is as a way of replacing methods. When a subclass declares a method in exactly the same manner as a method contained in one of its superclasses, the method of the superclass is replaced by the method of the subclass. Figure 7.1 gives a topological view of the relationship between class Book and class paperback.

Figure 7.1 : Topology of the class Book and class paperback.

Just as methods and variables can have access modifiers, classes also can have modifiers. To see this, you can add an additional keyword to the class Book before the keyword class:


   [class modifier]  class Book {



   }

In this example, you did not add anything in front of the class Book. Does that mean that the class modifier is undefined? No. When you do not specify a modifier in front of a variable, method, or class, a default is assumed, which in this case is friendly. The following list gives class modifier keywords and a brief explanation of each one:

abstractThis means that you want this class to be a general holding tank (that is, the root of a Java class hierarchy) containing only definitions that will be implemented in a subclass down the hierarchy.
finalThis means that you want this class to be the final class (for example, the root). In other words, when declaring a class final, you are specifying that the class cannot be a subclass.
publicThis means that the program is accessible to any class outside of the package. However, only one public class can be put in a file, and the file must be called the same name as the class with the extension of .java.
friendlyThis is the assumed class modifier for a class when nothing is declared-it is the class modifier for the class Book. This modifier will give access to any other class in the package.
synchronizableThis enables instances of a class to be made into arguments.

NOTE
You can have more than one class modifier for a particular class, as shown in this example:
public static void [Class Name] {
}

Classes, Methods, Inheritance, and Method Overriding-The Workshop

This section is a quick overview of how to compile Java programs.

To start demonstrating the material just presented, you will be using the JDK 1.0 command-line compiler to create your first Java program in a real-life scenario. If you do not have the JDK, which stands for Java Developers Kit, you can download it at the following site:


http://java.sun.com/download.html

Programs can be written in any text editor or in a proprietary development environment, although this might make it a little harder for you to follow along, because I am using the JDK 1.0. The program essentially displays the words Hello World (see Listing 7.1).


Listing 7.1. Hello World.

public class HelloWorld {

   public static void main( String argv[]) {

      System.out.println("Hello World");

   }

}


You must save the file as HelloWorld.java. Notice that the name of the file is the same as the name of the class, and that it has matching case. This is not because I am an organized programmer-it is because HelloWorld will not compile unless it is called exactly what you see in the preceding example. The reason for this is that you declared the class HelloWorld to be public. Any time you declare a class public, the file must be the same name as that class; the extension of .java is assumed. Your next step in the development cycle is to make sure you have the Java compiler and the HelloWorld.java file in the same directory, then at the DOS command line type the following:


javac HelloWorld.java

If everything runs smoothly when you compile, you will receive no error message from the compiler. You have just created a file called HelloWorld.class. The .class file is the executable file. The .java file is the development file and does not need to be present to run the program.

Here is exactly what to type to start the interpreter and to run your newly created class:


java HelloWorld

You will receive this statement on your screen:


Hello World

At this point you might not have understood everything that occurred at the programmatic level-that will be explained in later sections. For now let's move on by creating some more object-based classes. Take a look at Listing 7.2.


Listing 7.2. Book revision 1.

class Book {

   int NumberofPages;

   void ShowStuff() {

      System.out.println("The number of pages 

      in this book is:  " + NumberofPages);

   }



   public static void main(String args[]) {

      Book MyFirstBook = new Book();

      MyFirstBook.NumberofPages = 100;

      MyFirstBook.ShowStuff();

   }

}


In the code in Listing 7.2, you see that a variable called NumberofPages is declared as an integer. Then you see the method ShowStuff() declared also. Both of these are declared to be friendly, which is the default.

The statement in the fourth line of Listing 7.2 is merely a way to print things out on the screen:


System.out.println("The number of pages in this book is:  " + NumberofPages);

When you put quotes around something in this statement, it will literally be put up on the screen. That is why it is known as a string literal. If you do not put quotes around it, however (for example, NumberofPages does not have any quotes), Java will assume it to be a variable and will print out the value of the variable. Right now all you need to know is that it will print whatever is between the parentheses.

The next method that I want to mention is main, shown in the following example:


public static void main(String args[]) {

The method main is discussed in further detail in Chapter 8, "Java Programming." What is important here is that main will make the program run at the command prompt.

Now let's focus attention on the following line from Listing 7.2:


Book MyFirstBook = new Book();

The keyword new is known as an operator. When used as it is here, it creates another instance of the class Book. The keyword new acts as the constructor for a class Book named MyFirstBook. Essentially, you have created an instance of the class Book. Now let's compile this program by typing the following:


javac Book.java

If everything was typed and run correctly and you did not receive any error messages on the screen, run the program by typing


java Book

The following should be displayed on the screen:


The number of pages in this book is:  100

Here is a list of some major points that have always snagged me-especially when I was just starting out. You might want to consider copying this list and putting it near your computer as a reference every time you develop a new program. If you are having problems compiling smoothly, check for the following:

These three troubleshooting tips will probably help about 80 percent of those having trouble with this program right now.

Now let's improve the class Book. The next revision in Listing 7.3 will unleash the power of using the operator new.


Listing 7.3. Book revision 2.

class Book {

   int NumberofPages;

   void ShowStuff() {

      System.out.println("The number of pages 

in this book is:  " + NumberofPages);

   }



   public static void main(String args[]) {

      //Create two instances of the class Book

      Book MyFirstBook = new Book();

      Book MySecondBook = new Book();



      //specify the variable for the 

      # of pages and print it out in the first book.

      MyFirstBook.NumberofPages = 100;

      MyFirstBook.ShowStuff();



      //specify the variable for the 

      # of pages in the second book and print it out.

      MySecondBook.NumberofPages = 10;

      MySecondBook.ShowStuff();



   }

}


The // tells the compiler that everything after it on that line is a comment. It is used in the same way as ' or REM in Visual Basic.

NOTE
Java uses the same syntax as C/C++ for comments. Comments are a way for you to provide documentation inside your code. The single line comment is denoted by the //. The multiple line comment is shown here:


/* This is an example of a multiple line comment

in Java and C/C++ /*

After compiling and running the program shown in Listing 7.3, you will begin to see the power of instancing with the new operator. The output of your run should be as follows:


The number of pages in this book is:  100

The number of pages in this book is: 

In this revision you have created two instances of the class Book. The first instance is named MyFirstBook and has 100 pages. The second is named MySecondBook and has 10 pages. Using the new operator and a few lines of code, you were able to create two completely separate objects of Book, each similar by design but unique by implementation, with its own special set of names and attributes. It is crucial that you understand this process of instancing, as you will be using it throughout the rest of the chapter.

You are now going to add a string variable into the program by declaring a string data type called bookTitle. You also are going to use the keyword private to limit the access of this variable to this class only (see Listing 7.4).


Listing 7.4. Book revision 3.

class Book {

   private String bookTitle;

   int NumberofPages;

   void ShowStuff() {

      System.out.println("The title of this book is:  " + bookTitle);

      System.out.println("The number of pages 

      in this book is:  " + NumberofPages);

   }



   public static void main(String args[]) {

      //Create two instances of the class Book

      Book MyFirstBook = new Book();

      Book MySecondBook = new Book();



      //specify the variable for the 

      # of pages and print it out in the first book.

      MyFirstBook.bookTitle = "Mathematics";

      MyFirstBook.NumberofPages = 100;

      MyFirstBook.ShowStuff();



      //specify the variable for the 

      # of pages in the second book and print it out.

      MySecondBook.bookTitle = "Small Book";

      MySecondBook.NumberofPages = 10;

      MySecondBook.ShowStuff();



   }

}


NOTE
The consistently used indentations in your programs here are not requirements for the program to work. Java looks for semicolons and brackets to understand its structure. The indentations are simply a feature to help anyone who reads your code to make logical sense out of the program. Because you might not be the only one looking at the code you have written, it is a good idea to get into the habit of using indentation.

In Listing 7.4 you added this line to the program:


System.out.println("The title of this book is:  " + bookTitle);

Notice the plus sign between the quoted statement and the variable. This is an example of string arithmetic, which enables you to add a variable and a statement quite painlessly, even if the data type of the variable is not a string. Also notice that in the method main both of the instances now have their own private string variable of bookTitle, which enables you to give each of your book instances a title.

Compile and run the program once again. Your output should be as follows:


The title of this book is:  Mathematics

The number of pages in this book is:  100

The title of this book is:  Small Book

The number of pages in this book is: 

CAUTION
Even though you might see the words string and variable in the same sentence, in Java, strings are actually objects.

Now you are going to take the paperback class discussed earlier and create a real-life version that will run at the command prompt. The class will be named paperback, which will inherit from the class Book. Open a new file called paperback.java and input the code from Listing 7.5.


Listing 7.5. paperback revision 1.

class paperback extends Book {

   String colorofBook;



   public static void main(String args[]) {

      // Create an instance of paperback

      paperback MyFirstpaperback = new paperback();



      // Set the number of pages using an inherited variable

      MyFirstpaperback.NumberofPages = 120;



      // Set the color of the book 

      using the String object named colorofBook in

      // this class.

      MyFirstpaperback.colorofBook = "Red";



      // Use the inherited function showStuff to display the number

      // of pages for this function.

      MyFirstpaperback.ShowStuff();

   }



}


Before compiling the program in Listing 7.5, notice that the following statement has the variable NumberofPages in it:


MyFirstpaperback.NumberofPages = 120;

You did not initialize it in this class, however, so some might argue that this program might give you an error message if you tried to compile it. Remember, though, that you are extending the class Book, and Book has an integer variable called NumberofPages. Also, Book has a method ShowStuff()-these variables and methods are already built into it.

Here is one of the most unleashing powers of object-oriented programming. You can take an old class (in this case Book) and create a new class (paperback) without touching the original class. In class Book you will be able to use all of the functionality of that class and even add more functionality in the subclass paperback.

After compiling and running it, the output should be as follows:


The title of this book is:  null

The number of pages in this book is:  120

Because you did not specify what the title to your book in the class paperback should be, the variable bookTitle was made equal to null by default. Let's update the class paperback instance MyFirstpaperback by giving it a title using the variable bookTitle, which is inherited from the class Book (see Listing 7.6).


Listing 7.6. paperback revision 2.

class paperback extends Book {

   String colorofBook;



   public static void main(String args[]) {

      // Create an instance of paperback

      paperback MyFirstpaperback = new paperback();



      // Set the number of pages using an inherited variable

      MyFirstpaperback.NumberofPages = 120;



      // Set the color of the book using the String object named colorofBook in

      // this class.

      MyFirstpaperback.colorofBook = "Red";



      //Set the title of the book by inheriting the variable bookTitle

      //from the class Book.

      MyFirstpaperback.bookTitle = "Programming on the Net";



      // Use the inherited function ShowStuff to display the number

      // of pages for this function.

      MyFirstpaperback.ShowStuff();

   }



}


Compile the program in Listing 7.6. Unless you did something wrong, you should have received an error message:


   paperback.java:17: Variable bookTitle 

in class paperback not accessible from class paperback.

        MyFirstpaperback.bookTitle = "Programming on the Net";

                        ^

1 error

Before explaining what this exact error message is trying to say, let's first understand the syntax of Java error messages and how to interpret them. Referencing Table 7.1, the Java compiler first displays the class where the error is located. In this case it is paperback.java. Even though you might have typed javac paperback.java, the Java compiler also checks the Book class because the Book class is referenced in the file paperback.java. If there happened to be any errors in the Book class, then even though you stated that you were compiling the paperback class, errors in the Book class would be listed as well.

The number after the word paperback.java is the line number of where the error occurred. Thus, you can go back into the code and fish out where the problem resides. After the colon, the Java compiler next gives you a brief explanation of the error; in this case it is saying:


Variable bookTitle in class paperback not accessible from class paperback.

Then, on the next line, it will display the line of code, followed underneath by a caret sign, which represents an arrow to show you where the compiler stopped when it caught the problem.


paperback.java:17: Variable bookTitle 

in class paperback not accessible from class paperback.

        MyFirstpaperback.bookTitle = "Programming on the Net";

                        ^

1 error

Table 7.1. Error messages in Java.

Java errorExplanation
paperback.javaFile where error occurred
17Line number
Variable bookTitle...Error description
MyFirstpaperback...Actual line of code
1 errorTotal number of errors and warnings

Now that you understand more about what the Java compiler is trying to tell you in its error messages, let's try to solve the problem with the program in Listing 7.6. First, you should remember that the variable bookTitle is not in the paperback class. That would not usually be a problem because the variable bookTitle was intended to be inherited from the Book class. So you should look at the Book class. The following is the line of code in the Book class in Listing 7.4, declaring the variable bookTitle:


private String bookTitle;

As you can see, the keyword private was placed in front of this variable declaration. What this means is that bookTitle is available only to the class Book. Thus, bookTitle is not available to the subclass of paperback. Logically it makes sense, but let's check the brief explanation the compiler gave you about why it could not compile the program:


   paperback.java:17: Variable bookTitle 

in class paperback not accessible from class paperback.

Once again this statement is telling you that the variable bookTitle is not accessible from the class paperback, which confirms the hypothesis that the access modifier keyword private in front of the variable bookTitle is causing the error. This situation also has exemplified the functionality of declaring something private. In this instance it seems obvious that you would receive an error message; but, when you are writing classes in the future, and you know that the variable will not be used outside of its respective class (or you don't want it accessed from outside of its respective class), you can use the above syntax to declare it private.

Method overriding is the final object technology for which you are going to create a real-life example. You will use method overriding in the subclass paperback to create a new method that will replace the method ShowStuff() as shown in Listing 7.7. This new method also will tell you the color of the paperback book.


Listing 7.7. paperback revision 3.

class paperback extends Book {

   String colorofBook;



   // Create our own string object for a title, 

since the variable bookTitle is not available.

   String paperbackBookTitle;



   void ShowStuff() {

      System.out.println("The title of this paperback book is:  

      " + paperbackBookTitle);

      System.out.println("The color of this book is:  " + colorofBook);

      System.out.println("The number of pages 

      in this book is:  " + NumberofPages);

   }



   public static void main(String args[]) {

      // Create an instance of paperback

      paperback MyFirstpaperback = new paperback();



      // Set the number of pages using an inherited variable

      MyFirstpaperback.NumberofPages = 120;



      // Set the color of the book using the String object named colorofBook in

      // this class.

      MyFirstpaperback.colorofBook = "Red";



      //Set the title of the book by using a local variable because

      //the variable bookTitle is declared private in the superclass

      //Book.

      MyFirstpaperback.paperbackBookTitle = "Programming on the Net";



      // Instead of using the inherited function ShowStuff from

      // the class Book.  Use an overrided method display

      // information about the paperback book.

      MyFirstpaperback.ShowStuff();

   }

}


If the program compiled and ran smoothly, you should have received the following message:


The title of this paperback book is:  Programming on the Net

The color of this book is:  Red

The number of pages in this book is:  120

Now you can see the power of method overriding because you are able to in effect make many improvements to the original class Book without ever having to touch its code. In Listing 7.8 you will see the final revision to the paperback class. This final revision incorporates three instances of the class paperback for three separate fictitious books.


Listing 7.8. paperback revision 4.

class paperback extends Book {

   String colorofBook;

   String paperbackBookTitle;



   // This is the method that will override the ShowStuff()

   // in the superclass Book

   void ShowStuff() {

System.out.println("The title of this paperback book is:

  " + paperbackBookTitle);

      System.out.println("The color of this book is:  " + colorofBook);

      System.out.println("The number of pages 

in this book is:  " + NumberofPages);

   }



   public static void main(String args[]) {

      // Create three instances of paperback

      paperback MyFirstpaperback = new paperback();

      paperback MySecondpaperback = new paperback();

      paperback MyThirdpaperback = new paperback();



      // Set the number of pages using an inherited variable for the

      // three instances.

      MyFirstpaperback.NumberofPages = 120;

      MySecondpaperback.NumberofPages = 200;

      MyThirdpaperback.NumberofPages = 25;



      // Set the color for three of the books using the String

      //object named colorofBook in this class.

      MyFirstpaperback.colorofBook = "Red";

      MySecondpaperback.colorofBook = "Blue";

      MyThirdpaperback.colorofBook = "Green";



      //Set the title for the three books by using a local variable

      //because the variable bookTitle is declared private in the superclass

      //Book.

      MyFirstpaperback.paperbackBookTitle = "Programming on the Net";

      MySecondpaperback.paperbackBookTitle = "The Future of the Internet";

      MyThirdpaperback.paperbackBookTitle = "Why We Surf";





      // Use the inherited function showNumberofPages to display information

      // for the three instances

      MyFirstpaperback.ShowStuff();

      MySecondpaperback.ShowStuff();

      MyThirdpaperback.ShowStuff();



   }

}


Read the comments in the code carefully to help you decipher what the program is saying. You should do the same when you create your own programs, so that other programmers looking at your code will know what you are saying. If everything in the program ran smoothly, it should have displayed the following:


The title of this paperback book is:  Programming on the Net

The color of this book is:  Red

The number of pages in this book is:  120

The title of this paperback book is:  The Future of the Internet

The color of this book is:  Blue

The number of pages in this book is:  200

The title of this paperback book is:  Why We Surf

The color of this book is:  Green

The number of pages in this book is: 

This concludes the first workshop, which covered a great deal of powerful material. If you grasped all the concepts, you are well on your way toward becoming an object-oriented programmer.

Method Overloading-The Discussion

Method overloading can be used to create several functions of the same name that will perform very similar tasks, but each is designed to handle a different set of data types.

NOTE
In C++ it is OK for several functions with the same name to be defined with different sets of parameters. This is known as function overloading. C++ also supports operator overloading. Operator overloading is a way to customize an operator's functionality and hence its manipulation of a given expression. A major reason why operator overloading is not supported in Java is for simplicity's sake.

NOTE
One major discrepancy between C++ and Java is that Java does not support operator overloading.

Method Overloading-The Workshop

In both C++ and Java, it is OK for any object to have overloaded methods (in other words, methods with the same name), but they must have different arguments. In Java it is not known as function overloading; instead it is known as method overloading. Listing 7.9 shows an example of method overloading in Java.


Listing 7.9. combining revision 1.

class combining {

   // First method

   void combine() {

      System.out.println("You did not specify anything to combine.");

   }



   // Second method overloaded

   void combine(String firstWord) {

      System.out.println("You have only stated one word: " + firstWord);

   }

   //Third method overloaded

   void combine(String firstWord, String secondWord) {

      System.out.println("Here are your combined words:

  " + firstWord + secondWord);

   }

   public static void main(String args[]) {

       //Create an instance of the class combining

      combining MyStatements = new combining();

      //Run the method combine (using the first overloaded method)

      MyStatements.combine();

      //Run the method combine (using the third overloaded method)

      MyStatements.combine("The", "End");

      //Run the method combine (using the second overloaded method)

      MyStatements.combine("Yes");

   }

}


Compile the program and run it. If all went well, you should have received the following as output:


You did not specify anything to combine.

Here are your combined words:  TheEnd

You have only stated one word: Yes

Using this example, you can appreciate the improved simplicity that method overloading provides. It is a very helpful way of making your program easier to understand.

Interfaces-The Discussion

Interface is a keyword used in Java to inherit a class of definitions, but not the implementation code contained in the methods. Because Java does not support multiple inheritance, interfaces are a solution for the functionality lost in multiple inheritance. Thus, you can also implement as many interfaces as necessary.


interface drive {



}

An interface enables you to develop a kind of multiple inheritance without making your program too complicated. Although Java officially enables only single inheritance, with classes you can add as many interfaces to your class as you want. The only catch is that with interfaces you cannot inherit implementation code. This is not really a catch-it is actually a feature. It is a means by which you can keep the best of both worlds. You can have the technology of multiple inheritance without the confusing nature that multiple inheritance is known for.

Say that you wanted to use a set of methods from each of several classes. You could create an interface and use it in each of the classes. Then you could override the method declared in the interface to carry out the method for a particular class. To demonstrate, let's create three classes called car, truck, and van:


class car {



}



class truck {



}



class van extends vehicle {



}

The classes truck and car have no superclasses. The class van is a subclass to the fictitious superclass vehicle.

Now define an interface called drive:


interface drive {



void firstgear();



void secondgear();



void thirdgear();

}

NOTE
Interface methods must be declared public or friendly. The default is used here, so that means it is declared friendly.

Now implement drive into the three classes:


class truck implements drive {

   public void firstgear() {

      // algorithm goes here to override the method  

      firstgear in the interface drive.

      // the code here is specific only to truck.



   }

   public void secondgear() {

      // algorithm goes here to override the method 

      in secondgear in the interface drive.

      // The code here is specific only to truck.



   }

   public void thirdgear () {

      //algorithm goes here to override the method 

      in thirdgear in the interface drive.

      // The code here is specific only to truck.



   }

}

The power in this program might not reveal itself until you actually use it on, for example, a sample animation applet, which you will do later in Chapter 8

If right now you are very frustrated by interfaces (as I know I was when I first worked with them), take a moment and breath deeply 10 times. Repeat to yourself "Java is cool" each time. Now let's go ahead and continue with the lesson:


class van extends vehicle implements drive {

   public void firstgear() {

      //algorithm goes here to override the method

      firstgear in the interface drive. With a



      // special method only for the class van.

   }

   public void secondgear() {

      //algorithm goes here to override the method 

      secondgear in the interface drive.

      // with a special method only for class van.

   }

      public void thirdgear() {

      //algorithm goes here to override the method 

      thirdgear in the interface drive.

      // with a special method only for class van.

   }



}

Here is where you will see most of the beauty of interfaces. You can use the exact same interface on several classes and in the class van. Even though van already has the class vehicle from which it inherits, van still can accept an interface. In fact, you can add more than one interface to a class. Here is an example implementing more than one interface:


class myclass extend mysuperclass implements ABC, XYZ, É  {

}

Finishing this lesson on interfaces, you will use the exact same interface drive and implement it into the class car.


class car implements drive {



   void firstgear() {

      // algorithm goes here to override the method  

      firstgear in the interface drive.

      // the code in here is specific only to the class car.

   }



   void secondgear() {

      // algorithm goes here to override the method 

      in secondgear in the interface drive.

      // the code in here is specific only to the class car.



   }



   void thirdgear () {

      //algorithm goes here to override the method 

      in thirdgear in the interface drive.

      // the code here is specific only to the class car.



   }

}

I have focused heavily on the object technology of interfaces because it is one of the more misunderstood features of Java. In fact, just about every time I am on CompuServe's Java Support Forum (GO JAVAUSER), there is someone confused by interfaces, who is leaving messages asking for help. Fortunately, friendly Java gurus are available 24 hours a day to take your call.

Interfaces-The Workshop

This section gives a real-life example of how using interfaces can help you. First, let's build two classes, adding and multiplying. The first class in Listing 7.10 is the class adding. You can start by creating a new file called adding.java and keying Listing 7.10 into it.


Listing 7.10. adding before implementation.

class adding {

   // Declare the three variables to hold our values

   int First;

   int Second;

   int Total;



   public static void main(String args[]) {

      // Create an instance of the class adding

      adding ad = new adding();



      // Give the first two variables a value

      ad.First = 10;

      ad.Second = 14;



   }

}


If you compiled the above class, you saw that it would compile and run. You did not include the statement System.out.println, however, so nothing will show up on the screen. You will add the System.out.println lines later on.

The next class you will create should be called multiplying (see Listing 7.11). Once again, create a new file and call it mutiplying.java. Then key Listing 7.11 into it.


Listing 7.11. multiplying before implementation.

class multiplying {

   // Declare the three variables to hold our values

   int Firstmulti;

   int Secondmulti;

   int Totalmulti;



   public static void main(String args[]) {

      // Create an instance of the class adding

 multiplying ml = new multiplying();



      // Give the first two variables a value

      ml.Firstmulti = 5;

      ml.Secondmulti = 5;



   }

}


These two classes need to be improved upon, because there is no code yet to actually do the adding or multiplying of the first two arguments, and because nothing is printed out on the screen to tell you the answer. The next step is to look at the interface combine in Listing 7.12. In the same directory as the last two, create a new file called combine.java; then add the code from Listing 7.12 into it.


Listing 7.12. Interface to combine and show things.

interface combine {

    void Combine();

    void ShowStatus();

}


Compile the interface class combine by typing


javac combine.java

Now you are going to use interfaces and method overriding together to make your first two classes functional. You will be using the same interface for both classes. Go back to the class adding.java and make the appropriate changes as shown in Listing 7.13.


Listing 7.13. adding after implementation.

class adding implements combine {

   // Declare the three variables to hold our values

   int First;

   int Second;

   int Total;

   public void Combine() {

      // Below is the overriding implementation code for the interface

      // combine

      Total = First + Second;

   }

    public void ShowStatus() {

      // Below is the overriding implementation code for the interface

      // combine

      System.out.println("The total for the class: " + Total);

   }

   public static void main(String args[]) {

      // Create an instance of the class adding

      adding ad = new adding();

      // Give the first two variables a value

      ad.First = 10;

      ad.Second = 14;

      // The method to combine the two numbers

      ad.Combine();

      // the method to combine show the numbers on the screen

      ad.ShowStatus();

   }

}


In Listing 7.13, notice the keyword implements in the first line of the class. This is how you inherit an interface into a class. The logic behind calling the keyword implements is that you are including the interface (in this case combine) to implement it into the class (adding). Next notice that the methods Combine() and ShowStatus() are the same methods as the ones coming from the interface combine. Finally, look at the statements of Combine() and ShowStatus(). Interface methods that are overriding with implementation code will be accessible to instances of the class adding.

Your next step is to compile and run the program. If everything runs correctly, you should receive this as the output:


The total for the class:

To exemplify the power of interfaces, you will do almost the same thing to the class multiplying. First you will implement the same interface and then override its methods as shown in Listing 7.14. Reopen multiplying.java and make the changes so that multiplying looks like Listing 7.14.


Listing 7.14. multiplying after implementation.

class multiplying implements combine {

   // Declare the three variables to hold our values

   int Firstmulti;

   int Secondmulti;

   int Totalmulti;

   public void Combine() {

      // Overiding implementation code.

      Totalmulti = Firstmulti * Secondmulti;

   }

   public void ShowStatus() {

      //Override the implementation code.

      System.out.println("The product of the two variables

      is:  " + Totalmulti);

   }

   public static void main(String args[]) {

      // Create an instance of the class adding

      multiplying mul = new multiplying();

      // Give the first two variables a value

      mul.Firstmulti = 5;

      mul.Secondmulti = 5;

      //invoke the method to find the product

      mul.Combine();

      //Show the result on the screen

      mul.ShowStatus();

      }

}


Essentially, you are doing the same thing (putting two values together), except that in the class multiplying you find the product of two numbers instead of the summation. Now compile the program, and you should receive the following message:


The product of the two variables is: 

This introduction to objects in Java was meant to catch the essence of the Java object paradigm. In the next section, you will build upon your foundation by understanding other aspects of the Java language.

Introduction to Java Structure

This section gives you an overview of the structure of Java. Some of the topics include primitive data types, control flow statements, and how to handle arrays. If you are a C/C++ programmer, this section will need skimming only. However, if you are not a C/C++ programmer or if you are on shaky ground with C/C++, it will be worth your time to read through the material and try the examples.

Primitive Data Types

Although object-oriented programming languages have incorporated many improvements over structured programming languages, you do need to know structured programming in order to program objects effectively. As you go through this section, think of these structure-oriented topics as your foundation.

Booleans-The Discussion

The keyword boolean was named after a famous English mathematician who developed a new form of algebra based on a form of logic that is used in probably every programming language today: Boolean logic with Boolean operators. The basic data type boolean can have either a value of true or a value of false. Also, a boolean cannot be converted to another type (casting types will be described later in this chapter). Below is an example of declaring a boolean:


boolean here = true;

Data types can be assigned a value when the are declared, or you can assign them a value later on during the program in an expression or statement. An interesting point about the data type boolean is that, if you do not declare a value for it explicitly, it is set with a default value of false.

Booleans-The Workshop

Let's demonstrate how a boolean would work by creating a file called ABC.java and then coding Listing 7.15 into it.


Listing 7.15. ABC.

class ABC  {

   // Initialize the boolean with the default value of false.

   boolean first;



   // initialize the boolean with the value explicitly set to false.

   boolean  second = false;



   // initialize the boolean with the value explicitly set to true.

   boolean third = true;



   void ShowBools() {



   //Print out the value of each of the three booleans

   System.out.println("The value of first is " + first);

   System.out.println("The value of second is " + second);

   System.out.println("The value of third is " + third);

   }



   public static void main(String args[]) {

   public static void main(String args[]) {

//Create an instance of the class ABC

ABC abc = new ABC();



      //Change the value of third to false.

      abc.third = false;



      //Show the three booleans on the screen with their respective values.

      abc.ShowBools();

   }

}


Compile and run the above example; you should receive the following results:


The value of first is false

The value of second is false

The value of third is false

Integer Types

The next basic type that you are going to learn about is the subset of integer types.

Notice that there is more than one integer type in Java. The reason for this is size. It all boils down to efficiency-the larger the size of the integer you need, the more memory that must be assigned. Granted, we are only talking bits, but the more integer types your program works with, the more size will play a role in the overall performance and overhead of the program.

It is important to create your programs to be as efficient as possible.

NOTE
Bit is short for binary digit, either 1 or 0 in the binary number system. In processing any information, a bit is the smallest unit of information handled by a computer.

The smallest integer that can be declared in Java is the byte. The word byte stands for binary term, which is a unit of information consisting of 8 bits. The data type byte got its name because it consists of 8 bits. Because byte is the smallest, it is the most efficient to use; however, it also has the smallest range. You can only assign a byte to have a value of -128 to 127. Here is an example of declaring a byte:


byte myVariable;

As you can see, the syntax declaring primitive data types remains pretty much the same as you learned when you declared classes in Java.

The next level up is the short data type, which is also an integer, but it is 16 bits in length. Based on binary arithmetic, because its bit width is twice as long as the type byte, that will raise its range by a power of two as compared to the byte. So the short has a range of -32,768 to 32,767.

After the short comes the int, which you used in the previous section. The primary reason for using int in the previous section was because its name was similar to integer, which might be confusing; int is a 32-bit value, which equates that it is twice the size of short, which makes its range raise from short by a power of 2 as well. The range of int is -2,147,483,648 to 2,147,483,647.

The last and largest integer value you can have in Java is the data type long. As you can probably guess, long is 64 bits in length, which makes it twice the size of int. This means that it has raised int's range by a power of 2, so it would now be -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

NOTE
All integer data types are initialized with a default value of zero.

No doubt long was created in case Java was ever used to compute the national debt. Use Table 7.2 as a quick reference to all of the integer types.

Table 7.2. Quick reference to integer data types.

Keyword
Size (in bits)
Low rangeHigh range
byte
8
-128127
short
16
-32,76832,767
int
32
-2,147,483,6482,147,483,647
long
64
-9,223,372,036,854,775,8089,223,372,036,854,775,807

Character Literal

Char, which stands for character literal, is a character that is usually enclosed in a set of single quotes. Java characters are stored in Unicode format. To you the programmer, that means that they are 16 bits in length.

NOTE
Literal means that what was printed in the code is exactly what will be shown on the screen.

NOTE
Java's data type char holds 16-bit Unicode characters as opposed to ANSI C/C++'s type char, which holds the 8-bit extended ASCII character set.

Here is an example of a character being initialized with a value:


char X = 'J';

There are some characters in Java that are nonprintable. Table 7.3 shows a list of the character codes for nonprintable characters.

Table 7.3. Character codes.

CodeDescription
\bBackspace
\fFormfeed
\nNewline
\tTab
\\Backslash
\' (Single quote)Because you surround your character literals with single quotes, these quotes will not be printed (for example, with 'I', 'b', '$', the only things that will be printed on the screen are I, b, $). If you want to actually print a single quote, then you need to use this syntax, \'.
\" (Double quote)String literals are basically a group of two or more characters that need to be surrounded by double quotes (for example, "This is a String literal").
\xddHexadecimal
\dddOctal
\uddddUnicode

Float and Double

Floating-point notation is used to handle very large numbers, very small numbers, and decimals. The following is an example of how you would declare a variable as a float or a double:


float myFloat;

double myDouble;

Floating-point numbers can be in standard or scientific notation. Here are several examples of valid floating-point values:


3.113   4.4e23   5.6E-40   4.2e-21

In Java, floating-point data types conform to the IEEE 754 standard. A float is known as a single-precision floating-point data type. A double is known obviously enough as a double-precision floating-point data type. The major difference between a float and a double is bit width. A float is only 32 bits long, and a double is 64 bits long. Because of this size differential, there is also a difference in how precise each of the two floating-point variables can be (see Table 7.4). Just like the integer types, floating-point numbers are initialized to a value of 0 as a default.

Table 7.4. Overview of Java's floating-point data type.

KeywordSize (in bits) PrecisionLow range High range
float32Single 3.4E -383.4E +38
double64Double 1.7E -3081.7E +308

NOTE
IEEE is an abbreviation for the Institute of Electrical and Electronic Engineers. This organization is noted for setting various standards in the computer industry. One of the most famous was the IEEE 802, which set standards for the physical and data link layers of local area networks.

Casting

Casting deals with changing from one data type to another. For example, imagine that you have a char and you want to change it to an int:


int X;

char Y;

X = (int) Y;

The idea of casting is fairly basic. Referring to the preceding example, you place the name of the new data type in parentheses in front of the current data type that you want to change. If you are casting to a larger bit width data type, however, you might not need to explicitly include the parentheses of the new data type. For example, if you were to cast from a byte to an int, it could be done in an implicit manner. The overall usage of casting in real-life programs is much more complex than this, however, and data can be lost through truncation if casting is not used properly.

Another use for casting is to convert some information from one data type to another type. When casting between primitive data types, the major complication lies in size differences among the different data types. Trying to cast from one size to another can be a major cause of data loss.

Let's go over some examples of safe and unsafe casts to see exactly why there is potential for data loss. Start by declaring an integer variable called Myshort:


short Myshort = 10000;

Now look at the variable from the inside. Referring to Table 7.2, you see that the short integer type is 16 bits in length. Table 7.5 shows you the binary value for each bit. Thus, variable MyShort has a value of 10000.

Table 7.5. Inside the variable MyShort.

Bit #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ValueofBit
0
0
1
0
0
1
1
1
0
0
0
1
0
0
0
0

In Table 7.5, the row ValueofBit shows the binary representation of the number 10000. Your next step is to cast it. In this case you are going to cast it to a byte. Looking at Table 7.2, you see that a byte is only 8 bits long, so you know that somewhere along the way Java will truncate 8 bits off the variable MyShort. Logically and without going to the binary level, you know that, based on the definition for the range of a byte, that it cannot be 10000. This also confirms that there will be a problem in this cast. But Java won't throw you an error message; instead, it will return an invalid value to your new variable. The following segment of code shows the casting of a variable MyShort to MyByte:


byte MyByte;

MyByte = (byte) MyShort;

Now take the new value for MyByte and look at it at the binary level in Table 7.6 to find out what the value of MyByte will be.

Table 7.6. Truncation of MyShort to MyByte.

Bit #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ValueofBit
0
0
1
0
0
1
1
1
0
0
0
1
0
0
0
0
Truncated?
Y
Y
Y
Y
Y
Y
Y
Y
N
N
N
N
N
N
N
N

Looking at Table 7.6, you see that the first 8 bits are truncated (in other words, "blown away"). The end result is that, when you query the value MyByte, you will get a value of 16!

NOTE
In the binary number system, zeros on the left do not affect the value of the binary number.

If all of the bits truncated in Table 7.6 were zeros, you would not have had a problem. If that had been the case, the largest value the variable MyShort could hold would have been -128 to 127, the exact range of the byte. I hope this helps you understand the usefulness and dangers of truncating variables.

To end this discussion, here is a list showing casting that will be safe 100 percent of the time. Notice in the list that you are going to a larger bit size when you are casting; so at the binary level you are simply adding zeros to the left, which does not affect the value of the binary number:

Casting Between Objects

Another more complex version of casting is the object technology of casting between instances of objects. For example, in Java you can implicitly cast from a superclass to a subclass without the worry of data loss, because technically the subclass is a more specific representation of the superclass. However, if you go the other way (from a subclass to a superclass), it must be done at an explicit level and can result in changes in references to instance variables.

When you cast between objects, it is practically the same as casting between data types, as mentioned earlier. For example, imagine that you had a superclass of printer and a subclass of laserprinter. The following is an example of how you would cast laserprinter into the superclass of printer:


printer X;

laserprinter Y;

Y = new printer();

X = (laserprinter) Y;

Operators

Operators are designated symbols that perform various tasks in expressions. If you have had any experience with programming, you have probably been exposed to operators. The next sections will build a common understanding of each of the groups of related operators in Java. Once again, if you are a proficient C/C++ programmer, these sections are scanning material only.

Arithmetic Operators

The arithmetic operators are easy to understand because you were probably taught them in your first algebra classes (see Table 7.7).

Table 7.7. Arithmetic operators.

Operator
Definition
Java rep.
Algebraic rep.
+
Addition
T + 7
T +
-
Subtraction
u - v
u - v
*
Multiplication
g * m
gm
/
Division
x / y
x/y (or) x ÷ y
%
Modulus
I % n
I mod n

The syntax of using arithmetic operators is extremely simple. The integer variables a and b are employed in the following example with several arithmetic operators to give an idea of how to use them:


// Declare the values for a and b

a = 5;

b = 10;

(a + b) //Using the Addition operator to receive

        //from the expression.

( 4 - 1) //Using the Subtraction operator to receive

         //from the expression.

( 10 / 5) //Using the Division operator to receive

          //from the expression.

One arithmetic operator that might not be familiar to everyone is the modulus operator. A modulus operation returns the remainder of a division as its answer. So, for example, 25 % 8 equals 1.

NOTE
As opposed to C/C++, Java enables % operands to be non-integers.

Assignment Operators

Another set of operators in Java is the assignment operators. These also are similar to C/C++. In Table 7.8, you see a fairly self-explanatory chart of available assignment operators. Essentially, the calculation takes place before the variable is assigned a value.

Table 7.8. Assignment operators.

Operator
Java rep.
Algebraic rep.
Assume a and b are integer variables
+=
a += b
a = a + b
-=
a -= b
a = a - b
*=
a *= b
a = a * b
/=
a /= b
a = a / b
%=
a %= b
a = a % b

Comparison, Logical, Incremental, and Decremental Operators

The terms comparison operators and logical operators refer to the relationships that values can have to each other. Later I discuss the incremental and decremental operators, which are easy to understand as well.

The logical operator focuses more on how operands relate to each other, while the comparison operator focuses on how they don't relate to each other. Table 7.9 shows a breakdown of the comparison operators in Java; Table 7.10 shows a list of the logical operators in Java. With comparison operators, if the comparison expression is true, then a boolean true is returned; and if the expression is not true, then false is returned.

Table 7.9. Comparison operators.

OperatorDefinition Example exp.
Returns
Assume a = 5 and b =2
==equal to a == 5
true
  b == 5
false
!=not equal to a != 5
false
  b != 5
true
<less than a < 5
false
  b < 5
true
>greater than a > 5
false
  b > 5
false
<=less than or equal to a <= 5
true
  b <= 5
true
>=greater than or equal to a >= 5
true
 b >= 5
false

Logical operators are expressions that also result in a return of true if the statement is true, and false if the statement is false. Table 7.10 shows the logical operators.

Table 7.10. Logical operators.

OperatorDefinition Example exp.
Returns
Assume a = 1 and b =0
& or &&and a && b
false
| or ||or a || b
true
^xor a ^ b
true
!not !b
true

The difference between the or (||) and the xor (^) is that with the or (||), one of the operands can be true or false, whereas with the xor (^) (exclusive or), one of the operands must be true and the other must be false.

Some other things to mention about the logical operators are the differences between the & and &&, and the | and ||. If you use the single | (or &), then Java will evaluate both sides no matter what the outcome. With the &&, if the left side is false, then the compiler stops and returns false for the evaluation. And with ||, if the left side (which also is evaluated first) is true, then the compiler stops and returns true for the whole statement. The | and & logical operators are not available in C/C++, because C/C++ does not support this functionality.

What is the advantage of having the partial evaluation (of || and &&) differential as opposed to the full evaluation (| &)? The answer: speed and efficiency.

The expressions in Listing 7.16 are very basic. Imagine that you had a 100-step process comparing a 10-step process. To squeeze as much efficiency out of a program as possible, you would use the double || (or &&) and put the 10-instruction-step evaluation on the left. Thus, if the 10-step process returned a false for the && (or true for the ||), then you could immediately skip the right side and continue with the program. Compound this efficiency by using the expression evaluation 10 times throughout your program and you should begin to see the advantages of having this functionality.

NOTE
C/C++ does not have an exclusive xor for logical operation. Java does, however, by using the ^ which is borrowed from the bitwise xor.

Listing 7.16 is a real-life example of using the logical operators.


Listing 7.16. Logic revision 1.

public class logic {

   //initial the integers

   boolean a;

   boolean b;



   void Show() {

      System.out.println("true means 1 and false means 0");

      // Logical operator and

      System.out.println("(a and b) " + (a && b));



      //Logical operator or

      System.out.println("(a or b) " + (a || b));



      //Logical operator xor (exclusive or)

      System.out.println("(a xor b) " + (a ^ b));



      }



   public static void main(String args[]) {

      logic L = new logic();



      // Declare variables for a and b. Try other values here

      L.a = true;

      L.b = false;



      // Print out the logical expressions

      L.Show();

   }

}


Compile and run the program. If everything went smoothly, your output should be as follows:


true means 1 and false means

(a and b)false

(a or b)true

(a xor b)true

Experiment with the values of a and b to see what other results you might receive.

The final operators that you will learn about in this section are the incremental and decremental operators. Table 7.11 shows how these relate to each other and how to use them.

Table 7.11. Incremental and decremental operators.

Operator
Definition
Algebraic rep.
Example exp.
Returns
Assume a = 5 with each line
++
pre-increment
a = a + 1
(++a * 2)
12 (a = 6)
 
post-increment
 
(a++ * 2)
10 (a = 6)
--
pre-decrement
a = a - 1
(--a * 3)
12 (a = 4)
 
post-decrement
 
(a-- * 3)
15 (a = 4)

NOTE
The difference between a pre- and post-increment/decrement operator is with pre-, the increment/decrement operation is performed first.

Bitwise Operators

Java supports the set bitwise operators. This section will give you a brief introduction.

With bitwise operators there is an easy-to-understand part and a hard-to-understand part. The easy part is that bitwise operators say exactly what they mean. Bitwise operators deal with a data type's bits. The hard part is in the implementation of these operators.

Unless you are planning to write an operating system, networking software, or diagnostic equipment program, bitwise operators are not very useful. The space and the scope of this book do not permit a detailed explanation of bitwise operators. However, if you intend to write such a system, software, or diagnostic equipment in Sun's new language, then look for an advanced C++ programming textbook. Because C/C++ and Java are similar, you should have no problem translating between the two to understand what you need to know.

Ternary Operator

One of C++'s, and now Java's, most fascinating operators is the ?. The ? operator (also known as the ternary operator) can be used as a control flow statement. Look at the following example of a ternary operator:


Expression1 ? Exp2 : Exp3

Using the preceding format, if Expression1 is true, then Exp1 is fired. Or, if Expression1 is false, then Exp3 is fired. This operator is very simple to understand and use.

Operator Precedence

As you conclude this discussion of the Java operator realm, now is a good time to mention operator precedence. This is another very simple form of logic that you probably learned in your first algebra classes. For example, let's look at the following mathematical statement:


5 + 2 * 3

The wrong answer for this expression is 21 (which would be derived by adding 5 and 2, then multiplying the result by 3). The correct way to find the value for the above expression is to multiply 2´3 first then add the result to 5, which yields 11. It is simple logic really-you are applying the algebraic rule that the multiplication comes before the addition. The same logic of precedence has been applied to computer programming language operators.

The following list gives an overview of operator precedence in Java. The highest precedence is first:

  1. . [] ()
  2. ++ -- !
  3. new
  4. * / %
  5. + -
  6. < <= > >=
  7. == !=
  8. &
  9. ^
  10. |
  11. &&
  12. ||
  13. ? :
  14. = += -=
    *= %= ^=

Control Flow

The control flow stuff is a basic feature of any programming language; however, its actual syntax tends to vary between environments. Java uses almost exactly the same syntax as C/C++ control flow statements. Most of the following material on control flow statements will be discussion-based, although you will have a chance to try it in a real-life example at the end of this chapter with the bubble sort algorithm.

The if Conditional

The best place to start is with the if conditional, which is a control flow statement that will execute a piece of code if a Boolean evaluation is equal to true. For example, let's imagine that you are a bank and you want to create an algorithm that would print out a note to waive the monthly fee if a particular bank account's balance was over $1,000:


int bankaccount;

if (bankaccount > 1000) {

   System.out.println("Your service fee for this account is waived");

   }

If the variable bankaccount is over $1,000, then the Boolean expression will return true, and any code inside the block (contained in the brackets) will be executed. However, if the variable is not over $1,000, then the block will not be executed.

Now suppose you wanted to create this algorithm to deduct $5 from the account if the balance falls under $1,000. This can be done by implementing the keyword else. What you will now have is two blocks of code; if the Boolean expression is true, then one block will be executed, or if the expression is false, then the other block will be executed. Below is the implementation of using else in the fictitious bank account algorithm:


int bankaccount;

if (bankaccount > 1000) {

   System.out.println("Your service fee for this account is waived");

} else {

bankaccount -= 5;

}

Now if someone's account is below $1,000, then the block after else will be executed (in this case it will deduct 5 from the integer variable bankaccount).

The last scenario uses the keyword combination of else if. With this you can actually have more than one set of evaluations occurring in one if conditional statement. So, in this bank example, let's say you want to charge people $7 if their account balance is below $500; $5 if their account balance is between $500 and $1,000; and no charge if their account balance is over $1,000:


int bankaccount;

if (bankaccount > 1000) {

   System.out.println("Your service fee for this account is waived");

} else if (bankaccount < 500) {

      bankaccount -= 7;

} else {

bankaccount -= 5;

}

The while Loops

There are two formats for the while loops. As you will see in the following example, the first of these formats is understood to execute a piece of code as long as the evaluation returns a true:


while (evaluation){

   //execute some code.

}

The other format for the while loop is the do-while loop:


do {

   //execute some code.

while (evaluation);

As shown here, this statement will do the same thing as the previous one except that it has reversed the order in which it is executing code and evaluating. Here the code will be executed first, then the evaluation will take place. Thus, code in a do-while loop will always execute at least once, but the code in a while loop might not execute at all.

The primary difference between the two while formats is the order of execution and evaluation. In the first format the evaluation will take place first, then the code will execute. In the second format the code will execute first, then the evaluation will take place.

The for Loop

The for loop is a very versatile control flow statement, mostly due to its flexibility. Essentially the for loop will iterate for a certain period, and with each loop it will execute a block of code. The following is an example of format in a for loop:


for (expression1; evaluation; expression2) {

   // execute some code

}

In this example's format, the for control flow statement works like this: expression1 is the starting point of the for loop. It will initialize any variables that need to be and also will initialize any other data that would be unique to the start of the loop. The evaluation is executed at every pass of the loop, each time calling expression2; and if the evaluation returns true, then the loop will continue. But if it returns false, the loop will end.

Thinking of a more practical example for the for loop, imagine that you wanted to print out the numbers from one to 100 on the screen. One way to do it would be to use the following piece of code:


for (int j = 1; j < 100; j++) {

   System.out.println(j);

}

NOTE
One thing that makes loops very useful is that you can have nested loops (in other words, a loop inside a loop). Nested loops can be double-edged swords, however, because although they do provide improved functionality, they also increase the complexity of the program. You will have a chance to work with nested loops in the example at the end of this chapter.

It is also OK to have a for loop that never ends (in other words, an infinite loop), though the practicality of it would be fairly unusual.

The switch Conditional

An easy way to think of a switch statement is to think of a traffic light on a busy day. In this scenario the traffic light is some sort of expression, and based on the result of the expression some lanes will stop and other lanes will go. The following shows a simple example of a switch statement:


switch (expression) {

   case const1:

   // code specific to case one goes here

   break;

   case const2:

   //code specific to case two goes here

   break;

   case const3:

   case const4:

   // specific code common to both 3 and 4 goes here

   break;

   default:

   //This is fired if none of the other cases were.

   break;

}

In the preceding code, notice that there is a break statement after every case. This tells the compiler to exit out of the case and not continue with the program. Notice with case const3 and const4, however, that if either of them is chosen, it is designated to run the same code. This is useful if you have a few results that require the same code to be fired.

Scope

When you are dealing with the structured topology of any programming language, including Java, you have to deal with variable scope. In one light you already have dealt with scope-you have access modifiers that you can put in front of your variable declarations to affect their availability to other classes as shown in Listing 7.1. But that kind of scope is geared to situations between classes. It is crucial to note that scope does affect whether a variable declared inside a method will be accessed outside of that method.

Right now you are only going to focus on a variable's access inside its own class. When dealing with a variable, a block of code is not available outside of that block. This also means that if you declared a variable inside a block of code, you can declare another variable with exactly the same name outside the block of code, and it will be its own variable. In a sense this follows the same concept as method overriding, except that in this case it could be called variable overriding.

Create a file called scope.java and key in the code from Listing 7.17. Then compile and run it.


Listing 7.17. scope revision 1.

class scope {

   void Show() {

      int c = 12; //initialize a new c which hides the one in main

      System.out.println("This is the c inside of Show(): " + c);

   }



   public static void  main(String args[]) {

      int c = 10;  //initialize c in main

      scope s = new scope();  // Create a new instance of scope()

      System.out.println("This is c inside of main 

before calling Show(): " + c);

      s.Show(); //This will initialize Show()

      System.out.println("This is the c inside the class 

after calling Show(): " + c);



   }

}


The program in Listing 7.17 shows a variable c being initialized inside of the method main. Then the method Show() is called; and inside Show() is another variable c. Notice that before Show() is called, you already have a c in the method with a different value from the newer c. Also notice that after the method Show(), the original c still has the same value as before.

Now compile and run the program. You should receive the following on your screen:


This is c inside of main before calling Show():

This is the c inside of Show():

This is the c inside the class after calling Show():

Arrays-The Discussion

In C/C++ an array is a consecutive group of memory locations that all have the same data type in common. To refer to a particular location or element in the array you would specify the name of the array or the position number. In C++ there is no data type for a string variable, so a programmer would use an array's characters instead. This method is more efficient and flexible using built-in string objects (like Java has).

The reason that Java deviated from C/C++ by creating its own object was that C/C++ does no bounds checking. Hence, all you need to do is access an array that is larger than the allocated amount and presto! Instant crash. Also, because of this open-endedness, the C/C++ array of characters model gives loopholes for people to tinker with data more easily. In Java, arrays are actually objects (just as strings are objects); so when you create an array, you are actually instancing an object of an array. And that is why, when you declare an array implicitly, you use the operator new.

Look at the following example in which you are initializing an array of five integer variables called group:


int group[] = new int[5];

NOTE
An alternative method of declaring the array group would be to put the brackets next to the keyword int as shown here:
int[] group = new int[5];

You have initialized an array of five integer variables that can be accessed by reference to the number of the location of the variable in the brackets.

NOTE
Just as in C/C++, the index of the array here starts with 0. So, in the example of group, the first element would be located at position group[0] and the fifth and final location would be located at group[4].

The following is an example of how you place a value in the third element in the array:


group[2] = 10;

Another way to declare arrays is by declaring all the values of the array explicitly. Thus, all the values are placed into the array up front:


int collection[] = {1, 13, 29, 9};

As you can see, the preceding example of an array has four elements. The array was initialized, and it was given a variable.

In general, arrays are a very common and basic programming technique. In Java, you can have multidimensional arrays. The following show how you would declare a two-dimensional array implicitly and explicitly:


int multigroups[] = new int[10][20];

int multigroups[] = {{1,2}, {2,4}, {4, 8}};

Arrays-The Workshop

This example is more geared toward the last several sections that dealt with control flow statements, scope, and finally arrays. In this workshop you are going to use the computer science field of sorting to exemplify an array in Java.

NOTE
Bubble sort, also known as exchange sort, is a sorting algorithm that starts at the end of a list and moves all the way through the list comparing adjacent values, and swapping them if they are not in the correct corresponding order.

The sorting algorithm is called the bubble sort. In effect, what you are going to do is take an array that has been initialized with a fairly random set of values, call the method bubbleSort() to sort it, and then redisplay the sorted array (see Listing 7.18). The focus of this workshop is to give you a chance to get some hands-on experience in working with array objects in Java. In addition, you will have a chance to work with some of the control flow statements that were discussed earlier in the chapter.


Listing 7.18. The sorting algorithm.

public class sort {



   public static void main(String args[]) {

      // Declare the array explicitly with a set of random numbers

      int nums[] = {1, 8, 5, 2, 9, 19, 3, 7};



      int size = 8;  // the number of variables in the array



      System.out.println("Original values for the array.");

      // Loop through to print out the original values

      // for the array



      for (int i = 1; i < size; i++) {

         System.out.println(nums[i]);

      }



      //The actual sort algorithm

      int temp;  // temporary holding tank for variables.



      for (int i = 1; i < size; i++) {

         for(int j = size -1; j >= i; j--) {

            if(nums[j - 1] > nums[j]) {

               //if out of order exchange

               temp = nums[j - 1];

               nums[j-1] = nums[j];

               nums[j] = temp;

            }

         }

      }



      System.out.println("Sorted values for the array");

      //loop through and display the sorted array.

      for (int i = 0; i < size; i++) {

         System.out.println(nums[i]);

      }

   }

}


Look at the program and study it, especially the nest algorithm. Then compile and run it. If everything ran smoothly, you should have received the output shown in Listing 7.19.


Listing 7.19. Original values for the array.

8

5

2

9

19

3

7

Sorted values for the array

1

2

3

5

7

8

9

19


Now that you have run it and seen its outcome, go back to the code to study it. Follow it, as the compiler might, through various scenarios. Then experiment with different values for the array. Also try different array sizes and see what you get. Through this experimentation, all of the techniques that were explained in the preceding sections should come together for you.

The bubble sort algorithm is not the most efficient sorting algorithm in the world, but its simplicity and relative efficiency with smaller algorithms make it an excellent tool to help you understand sorting, control flow statements, and algorithms in general.

Summary

This chapter was specifically designed to give you a foundation of common understanding of the Java programming language. None of the programs focused very much on graphics in Java or the Internet. However, this chapter was a stepping stone to understanding the next chapter, which will in effect assume that all of the concepts in this chapter are understood.

Chapter 8 "Java Programming," gives you an opportunity to focus on the applet side of Java and how to develop real-life Java applets for the Internet.