Sunday, December 28, 2008

Using Arrays

Using Arrays

I could use a raise.

Oh, arrays. Sorry.

Arrays are an important aspect of any programming language, and Java is no exception. In this chapter, you discover just about everything you need to know about using arrays. I cover run-of-the-mill one-dimensional arrays, multi-dimensional arrays, and two classes that are used to work with arrays, named Array and Arrays.

Understanding Arrays

An array is a set of variables that are referenced using a single variable name combined with an index number. Each item of an array is called an element. All the elements in an array must be of the same type. Thus the array itself has a type that specifies what kind of elements it can contain. For example, an int array can contain int values, and a String array can contain strings.

The index number is written after the variable name and enclosed in brackets. So, if the variable name is x, you could access a specific element with an expression like x[5].


Tip

You might think x[5] would refer to the fifth element in the array. But index numbers start with zero for the first element, so x[5] actually refers to the sixth element. This little detail is one of the chief causes of problems when working with arrays-especially if you cut your array-programming teeth in a language in which arrays are indexed from 1 instead of 0. So get used to counting from 0 instead of from 1.

The real power of arrays comes from the simple fact that you can use a variable or even a complete expression as an array index. So (for example) instead of coding x[5] to refer to a specific array element, you can code x[i] to refer to the element indicated by the index variable i. You see plenty of examples of index variables throughout this chapter.

Here are a few additional tidbits of array information to ponder before you get into the details of creating and using arrays:

  • An array is itself an object. You can refer to the array object as a whole rather than a specific element of the array by using the array's variable name without an index. Thus, if x[5] refers to an element of an array, x refers to the array itself.

  • An array has a fixed length that's set when the array is created. This length determines the number of elements that can be stored in the array. The maximum index value you can use with any array is one less than the array's length. Thus, if you create an array of ten elements, you can use index values from 0 to 9.

  • You can't change the length of an array after you create the array.

  • You can access the length of an array by using the length field of the array variable. For example, x.length returns the length of the array x.

Thursday, December 25, 2008

Work with Strings

Working with Strings

Strings are one of the most common types of objects in Java. Throughout this book are various techniques for working with strings. You've seen how to create string variables, how to concatenate strings, and how to compare strings. But so far, I've only scratched the surface of what you can do with strings. In this chapter, I dive deeper into what Java can do with string. (Hint: Way more than Cat's Cradle.)

I start with a brief review of what I covered so far about strings, so you don't have to go flipping back through the book to find basic information. Then I look at the String class itself and some of the methods it provides for working with strings. Finally, you examine two almost identical classes named StringBuilder and StringBuffer that offer features not found in the basic String class.

Reviewing Strings

To save you the hassle of flipping back through this book, the following paragraphs summarize what is presented in earlier chapters about strings:

  • Strings are reference types, not value types, such as int or boolean.

    As a result, a string variable holds a reference to an object created from the String class, not the value of the string itself.

  • Even though strings aren't primitive types, the Java compiler has some features designed to let you work with strings almost as if they were. For example, Java lets you assign string literals to string variables, like this:

         String line1 = "Oh what a beautiful morning!";

  • Strings can include escape sequences that consist of a slash followed by another character. The most common escape sequences are \n for new line and \t for tab. If you want to include a slash in a string, you must use the escape sequence \\.

  • Strings and characters are different. String literals are marked by quotation marks; character literals are marked by apostrophes. Thus “a” is a string literal that happens to be one character long. In contrast, ‘a’ is a character literal.

  • You can combine, or concatenate, strings by using the + operator, like this:

         String line2 = line1 + "\nOh what a beautiful day!";
  • You can also use the += operator with strings, like this:

         line2 += = "\nI've got a beautiful feeling";
  • When used in a concatenation expression, Java automatically converts primitive types to strings. Thus Java allows the following:

         int empCount = 50;
    String msg = "Number of employees: " + empCount;

  • The various primitive wrapper classes (such as integer and double) have parse methods that can convert string values to numeric types. Here's an example:

         String s = "50";
    int i = Integer.parseInt(s);
  • You can't compare strings using the equality operator (==). Instead, you should use the equals method. Here's an example:

         if (lastName.equals("Lowe"))
    System.out.println("This is me!");
  • The String class also has an equalsIgnoreCase method that compares strings without considering case. Here's an example:

         if (lastName.equalsIgnoreCase("lowe"))
    System.out.println("This is me again!");

DESIGN PATTERN

Tuesday, December 23, 2008

Package and Document

Packaging and Documenting Your Classes

Now that you know just about everything there is to know about creating classes, this chapter shows you what to do with the classes you create. Specifically, I show you how to organize your classes into neat packages. Packages enable you to keep your classes separate from classes in the Java API, allow you to reuse your classes in other applications, and even let you distribute your classes to others, assuming other people might be interested in your classes.

If that's the case, you probably won't want to just send those people all your separate class files. Instead, you want to bundle them into a single file called a JAR file. That's covered in this chapter too.

Finally, you find out how to use a feature called JavaDocs that lets you add documentation comments to your classes. With JavaDocs, you can build professional-looking documentation pages automatically. Your friends will think you're a real Java guru when you post your JavaDoc pages to your Web site.

Working with Packages

A package is a group of classes that belong together. Without packages, the entire universe of Java classes would be a huge unorganized mess. Imagine the thousands of classes that are available in the Java API combined with millions of Java classes created by Java programmers throughout the world, all thrown into one big pot. Packages let you organize this pot into smaller, manageable collections of related classes.

Importing classes and packages

When you use import statements at the beginning of a Java source file, you make classes from the packages mentioned in the import statements available throughout the file. (I cover import statements in Book II, Chapter 1, but it doesn't hurt to repeat it here.)

An import statement can import all the classes in a package by using an asterisk wildcard:

import java.util.*;

Here all the classes in the java.util package are imported.

Alternatively, you can import classes one at a time:

import java.util.ArrayList;

Here just the ArrayList class is imported.


Note

You don't have to use an import statement to use a class from a package. But if you don't use an import statement, you must fully qualify any references to the class. For example, you can use the ArrayList class without importing java.util:

java.util.ArrayList = new java.util.ArrayList();

Because fully qualified names are a pain to always spell out, you should always use import statements to import the packages or individual classes your application uses.

You never have to explicitly import two packages:

  • java.lang: This package contains classes that are so commonly used that the Java compiler makes them available to every program. Examples of the classes in this package are String, Exception, and the various wrapper classes, such as Integer and Boolean.

  • The default package: This package contains classes that aren't specifically put in some other package. All the programs I show in this book up to this point rely on the default package.

For simple program development and experimentation, using the default package is acceptable. However, if you start work on a serious Java application, create a separate package for it and place all the application's classes there. You find out how to do that in the next section.


TECHNICAL STAUFF

You can't import the default package, even if you want to. Suppose you have two packages-the default package and the com.lowewriter.util package. The default package's code contains the statement import com.lowewriter.util.*. That's okay. But the default package doesn't have a name-at least it has no name that you can use inside a program. The com.lowewriter.util package's code can't contain a statement like import that_default_package.you_know.the_one_with_no_name.

Creating your own packages

Creating your own packages to hold your classes is easy. Well, relatively easy anyway. You must go through a few steps:

  1. Pick a name for your package.

    You can use any name you wish, but I recommend you follow the established convention of using your Internet domain name (if you have one), only backwards. I own a domain called http://www.LoweWriter.com, so I use the name com.lowewriter for all my packages. (Using your domain name backwards ensures that your package names are unique.)

    Notice that package names are in all-lowercase letters. That's not an absolute requirement, but it's a Java convention that you ought to stick to. If you start using capital letters in your package names, you'll be branded a rebel for sure.


    Tip

    You can add additional levels beyond the domain name if you want. For example, I put my utility classes in a package named com.lowewriter. util.

    If you don't have a domain all to yourself, try using your e-mail address backwards. For example, if your e-mail address is SomeBody@SomeCompany.com, use com.somecompany.somebody for your package names. That way they are still unique. (If you ever want to distribute your Java packages, you should register a domain name. Nothing says "Amateur" like a package name that starts with com.aol.)

  2. Choose a directory on your hard drive to be the root of your class library.

    You need a place on your hard drive to store your classes. I suggest you create a directory such as c:\javaclasses.

    This folder becomes the root directory for your Java packages.

  3. Create subdirectories within the root directory for your package name.

    For example, for the package named com.lowewriter.util, create a directory named com in the c:\javaclasses directory (assuming that's the name of your root). Then, in the com directory, create a directory named lowewriter. Then, in lowewriter, create a directory named util. Thus, the complete path to the directory that contains the classes for the com.lowewriter.util package is c:\javaclasses\ com\lowewriter\util.

  4. Add the root directory for your package to the ClassPath environment variable.

    The exact procedure for doing this depends on your operating system. In Windows XP and Vista, you can set the ClassPath by double-clicking System from the Control Panel. Click the Advanced tab, and then click Environment Variables.

    Be careful not to disturb any directories already listed in the ClassPath. To add your root directory to the ClassPath, add a semicolon followed by the path to your root directory to the end of the ClassPath value. For example, suppose your ClassPath is already set to this:

         .;c:\util\classes

    Then you modify it to look like this:

         .;c:\util\classes;c:\javaclasses

    Here I added ;c:\javaclasses to the end of the ClassPath value.

  5. Save the files for any classes you want to be in a particular package in the directory for that package.

    For example, save the files for a class that belongs to the com.lowewriter.util package in c:\javaclasses\com\ lowewriter\util.

  6. Add a package statement to the beginning of each source file that belongs in a package.

    The package statement simply provides the name for the package that any class in the file is placed in. For example:

         package com.lowewriter.util;

    REMEMBER

    The package statement must be the first non-comment statement in the file.

An example

Suppose you've developed a utility class named Console that has a bunch of handy static methods for getting user input from the console. For example, this class has a static method named askYorN that gets a Y or N from the user and returns a boolean value to indicate which value the user entered. You decide to make this class available in a package named com.lowewriter.util so you and other like-minded programmers can use it in their programs.

Here's the source file for the Console class:

package com.lowewriter.util;

import java.util.Scanner;

public class Console
{

static Scanner sc = new Scanner(System.in);

public static boolean askYorN(String prompt)
{
while (true)
{
String answer;
System.out.print("\n" + prompt
+ " (Y or N) ");
answer = sc.next();
if (answer.equalsIgnoreCase("Y"))
return true;
else if (answer.equalsIgnoreCase("N"))
return false;
}
}
}

Okay, so far this class has just the one method (askYorN), but one of these days you'll add a bunch of other useful methods to it. In the meantime, you want to get it set up in a package so you can start using it right away.

So you create a directory named c:\javaclasses\com\lowewriter\util (as described in the preceding section) and save the source file to this directory. Then you compile the program so the Console.class file is stored in that directory too. And you add c:\javaclasses to your ClassPath environment variable.

Now you can use the following program to test that your package is alive and well:

import com.lowewriter.util.*;

public class PackageTest
{
public static void main(String[] args)
{
while (Console.askYorN("Keep going?"))
{
System.out.println("D'oh!");

}
}
}

Here the import statement imports all the classes in the com.lowewriter. util package. Then, the while loop in the main method repeatedly asks the user if he or she wants to keep going.

Sunday, December 21, 2008

Inner Classes

Using Inner Classes
In this chapter, you find out how to use three advanced types of classes: inner classes, static inner classes, and anonymous inner classes. All three are useful in certain circumstances. In particular, inner classes and anonymous inner classes are commonly used with graphical applications created with Swing. For more information about Swing, refer to Book VI. In this chapter, I just concentrate on the mechanics of creating these types of classes.

TECHNICAL STAUFF Once again, this chapter could have a Technical Stuff icon pasted next to every other paragraph. The immediate usefulness of some of the information I present in this chapter may seem questionable. But trust me-you need to know this stuff when you start writing Swing applications. If you want to skip this chapter for now, that's okay. You can always come back to it when you're learning Swing and you need to know how inner classes and anonymous inner classes work.


Declaring Inner Classes
An inner class is a class that's declared inside of another class. Thus the basic structure for creating an inner class is as follows:

class outerClassName
{
private class innerClassName
{
// body of inner class
}
}

The class that contains the inner class is called an outer class. You can use a visibility modifier with the inner class to specify whether the class should be public, protected, or private. This visibility determines whether other classes can see the inner class.

Understanding inner classes
At the surface, an inner class is simply a class that's contained inside another class. However, there's more to it than that. Here are some key points about inner classes:

An inner class automatically has access to all the fields and methods of the outer class-even private fields and methods. Thus an inner class has more access to its outer class than a subclass has to its super-class. (A subclass can access public and protected members of its superclass, but not private members.)

An inner class carries with it a reference to the current instance of the outer class that enables it to access instance data for the outer class.

Because of the outer class instance reference, you can't create or refer to an inner class from a static method of the outer class. You can, however, create a static inner class, as I describe in the section "Using Static Inner Classes" later in this chapter.

Tip One of the main reasons for creating an inner class is to create a class that's only of interest to the outer class. As a result, you usually declare inner classes to be private so other classes can't access them.


Occasionally, code in an inner class needs to refer to the instance of its outer class. To do that, you list the name of the outer class followed by the dot operator and this. For example, if the outer class is named MyOuterClass, you would use MyOuterClass.this to refer to the instance of the outer class.

An example
Book III, Chapter 5 introduces an application that uses the Timer class in the Swing package (javax.swing.Timer) that displays the lines Tick… and Tock… on the console at a one-second interval. It uses a class named Ticker that implements the ActionListener interface to handle the Timer object's clock events.

Tip In this chapter, you see a total of three different versions of this application. You may want to quickly review Book III, Chapter 5 if you're unclear on how this application uses the Timer class to display the Tick… and Tock… messages, or why the JOptionPane dialog box is required.


Listing 7-1 shows a version of this application that implements the Ticker class as an inner class.

Listing 7-1: Tick Tock with an Inner Class



import java.awt.event.*;
import javax.swing.*;

public class TickTockInner
{
private String tickMessage = "Tick..."; → 6
private String tockMessage = "Tock..."; → 7
public static void main(String[] args)
{
TickTockInner t = new TickTockInner(); → 11
t.go(); → 12
}

private void go() → 15
{
// create a timer that calls the Ticker class
// at one second intervals
Timer t = new Timer(1000, new Ticker()); → 19
t.start();

// display a message box to prevent the
// program from ending immediately
JOptionPane.showMessageDialog(null, → 24
"Click OK to exit program");
System.exit(0); → 26
}

class Ticker implements ActionListener → 29
{
private boolean tick = true;

public void actionPerformed(ActionEvent event) → 33
{
if (tick)
{
System.out.println(tickMessage); → 37
}
else
{
System.out.println(tockMessage); → 41
}
tick = !tick;
}
}
}






The Observer pattern
Event listeners in Java are part of a Java model called the Delegation Event Model. The Delegation Event Model is an implementation of a more general design pattern called the Observer pattern. This pattern is useful when you need to create objects that interact with each other when a change in the status of one of the objects occurs. The object whose changes are being monitored is called the observable object, and the object that monitors those changes is called the observer object.

The observer object registers itself with the observable object, which then notifies the observer object when its status changes.

You discover more about how Java implements this pattern for event handling in Book VI. But if you're interested, you may want to investigate the Observer and Observable interfaces that are a part of the Java API. They provide a standard way to create simple implementations of the Observer pattern.





The following paragraphs describe some of the highlights of this program:

→ 6
The String variables named tickMessage and tockMessage (line 7) contain the messages to be printed on the console. Note that these variables are defined as fields of the outer class. As you'll see, the inner class Ticker is able to directly access these fields.

→ 11
Because an inner class can only be used by an instantiated object, you can't use it directly from the static main method. As a result, the main method in this program simply creates an instance of the application class (TickTockInner).

→ 12
This line executes the go method of the new instance of the TickTockInner class.

Tip The technique used in lines 11 and 12 is a fairly common programming technique that lets an application quickly get out of a static context and into an object-oriented mode.

Open table as spreadsheet
→ 15
The go method, called from line 12.

→ 19
This line creates an instance of the Timer class with the timer interval set to 1,000 milliseconds (1 second) and the ActionListener set to a new instance of the inner class named Ticker.

→ 24
Here the JOptionPane class is used to display a dialog box. This dialog box is necessary to give the timer a chance to run. The application ends when the user clicks OK.

→ 26
This line calls the exit method of the System class, which immediately shuts down the Java Virtual Machine. This method call isn't strictly required here, but if you leave it out, the timer continues to run for a few seconds after you click OK before the JVM figures out that it should kill the timer.

→ 29
This line is the declaration for the inner class named Ticker. Note that this class implements the ActionListener interface.

→ 33
The actionPerformed method is called by the Timer object every 1,000 milliseconds.

→ 37
In this line and in line 41, the inner class directly accesses a field of the outer class.

Friday, December 19, 2008

Object and Class

Using the Object and Class Classes

In this chapter, you find out how to use two classes of the Java API that are important to object-oriented programming:

  • The Object class, which every other class inherits-including all the classes in the Java API and any classes you create yourself

  • The Class class, which is used to get information about an object's type


TECHNICAL STAUFF

If I could, I'd plant a huge Technical Stuff icon on this entire chapter. All this stuff is a bit on the technical side, and many Java programmers get by for years without understanding or using it. Still, I recommend you read this chapter carefully. Even if it all doesn't sink in, it may help explain why some things in Java don't work quite the way you think they should, and the information in this chapter may someday help you program your way out of a difficult corner.

The Mother of All Classes: Object

Object is the mother of all classes. In Java, every class ultimately inherits the Object class. This class provides a set of methods that are available to every Java object.

Every object is an Object

Any class that doesn't have an extends clause implicitly inherits Object. Thus you never have to code a class like this:

public class Product extends Object...

If a subclass has an extends clause that specifies a superclass other than Object, the class still inherits Object. That's because the inheritance hierarchy eventually gets to a superclass that doesn't have an extends clause, and that superclass inherits Object and passes it down to all its subclasses.

For example, suppose you have these classes:

public class Manager extends SalariedEmployee...

public class SalariedEmployee extends Employee...

public class Employee extends Person...

public class Person...

Here the Manager class inherits the Object class indirectly because it inherits SalariedEmployee, which inherits Employee, which inherits Person, which inherits Object.


REMEMBER

In Java, creating a class that doesn't inherit Object is not possible.

Using Object as a type

If you don't know or care about the type of an object referenced by a variable, you can specify its type as Object. For example, the following is perfectly legal:

Object emp = new Employee();

However, you can't do anything useful with the emp variable, because the compiler doesn't know it's an Employee. For example, if the Employee class has a method named setLastName, the following code doesn't work:

Object emp = new Employee();
emp.setLastName("Smith"); // error: won't compile

Because emp is an Object, not an Employee, the compiler doesn't know about the setLastName method.

Note that you could still cast the object to an Employee:

Object emp = new Employee();
((Employee)emp).setLastName("Smith"); // this works

But what's the point? You may as well make emp an Employee in the first place.

Declaring a variable, parameter, or return type as Object, however, in certain situations does make perfect sense. For example, the Java API provides a set of classes designed to maintain collections of objects. One of the most commonly used of these classes is the ArrayList class. It has a method named add that accepts an Object as a parameter. This method adds the specified object to the collection. Because the parameter type is Object, you can use the ArrayList class to create collections of any type of object. (For more information about the ArrayList class and other collection classes, see Book IV.)

Methods of the Object class

Table 6-1 lists all the methods of the Object class. Ordinarily, I wouldn't list all the methods of a class-I'd just list the ones that I think are most useful. However, because Object is such an important player in the game of object-oriented programming, I thought showing you all its capabilities is best, even though some of them are a bit obscure.

Table 6-1: Methods of the Object Class
Open table as spreadsheet

Method

What It Does

protected Object clone()

Returns a copy of this object.

boolean equals(Object obj)

Indicates whether this object is equal to the obj object.

protected void finalize()

Called by the garbage collector when the object is destroyed.

Class getClass()

Returns a Class object that represents this object's runtime class.

int hashCode()

Returns this object's hash code.

void notify()

Used with threaded applications to wake up a thread that's waiting on this object.

void notifyAll()

Used with threaded applications to wake up all threads that are waiting on this object.

String toString()

Returns a String representation of this object.

void wait()

Causes this object's thread to wait until another thread calls notify or notifyAll.

void wait(Long timeout)

A variation of the basic wait method.

void wait (Long timeout, int nanos)

Yet another variation of the wait method.


TECHNICAL STAUFF

I warned you-this entire chapter should have a Technical Stuff icon.


Note

Almost half of these methods (notify, notifyAll, and the three wait methods) are related to threading. You find complete information about those five methods in Book V, Chapter 1. Here's the rundown on the remaining six methods:

  • clone: This method is commonly used to make copies of objects, and overriding it in your own classes is not uncommon. I explain this method in detail later in this chapter, in the section "The clone Method."

  • equals: This method is commonly used to compare objects. Any class that represents an object that can be compared with another object should override this method. Turn to the section "The equals Method" later in this chapter, for more info.

  • finalize: This method is called when the garbage collector realizes that an object is no longer being used and can be discarded. The intent of this method was to allow you to create objects that clean up after themselves by closing open files and performing other clean-up tasks before being discarded. But because of the way the Java garbage collector works, there's no guarantee that the finalize method actually ever is called. As a result, this method isn't commonly used.

  • getClass: This method is sometimes used in conjunction with the Class class, which I described later in this chapter in the section "The Class Class."

  • hashCode: Every Java object has a hash code, which is an int representation of the class that's useful for certain operations. This method isn't terribly important until you start to work with hash tables-which is a pretty advanced technique, best left to people with pocket protectors and tape holding their glasses together.

  • toString: This method is one of the most commonly used methods in Java. I describe it in the section "The toString Method" later in this chapter.

Primitives aren't objects

I need to note that primitive types, such as int and double, are not objects. As a result, they do not inherit the Object class and don't have access to the methods listed in the previous section.

As a result, the following code won't work:

int x = 50;
String s = x.toString(); // error: won't compile

If you really want to convert an int to a string in this way, you can use a wrapper class such as Integer to create an object from the value, and then call its toString method:

String s = new Integer(x).toString(); // OK

Each of the wrapper classes also defines a static toString method you can use like this:

String s = Integer.toString(x);

Tip

Sometimes using the compiler shortcut that lets you use primitive types in string concatenation expressions is easier:

String s = "" + x;

Here the int variable x is concatenated with an empty string.

Wednesday, December 17, 2008

Abstract Classes

Using Abstract Classes and Interfaces

In this chapter, you find out how to use two similar but subtly distinct features: abstract classes and interfaces. Both let you declare the signatures of the methods and fields that a class implements separately from the class itself. Abstract classes accomplish this by way of inheritance. Interfaces do it without using inheritance, but the effect is similar.

Using Abstract Classes

Java lets you declare that a method or an entire class is abstract, which means that the method has no body. An abstract method is just a prototype for a method: a return type, a name, a list of parameters, and (optionally) a throws clause.

To create an abstract method, you specify the modifier abstract and replace the method body with a semicolon:

public abstract int hit(int batSpeed);

Here the method named hit is declared as an abstract method that returns an int value and accepts an int parameter.

A class that contains at least one abstract method is called an abstract class, and must be declared with the abstract modifier on the class declaration. For example:

public abstract class Ball
{
public abstract int hit(int batSpeed);
}

Warning

If you omit the abstract modifier from the class declaration, the Java compiler coughs up an error message to remind you that the class must be declared abstract.

An abstract class can't be instantiated. Thus, given the preceding declaration, the following line doesn't compile:

Ball b = new Ball();   // error: Ball is abstract

The problem here isn't with declaring the variable b as a Ball. It's using the new keyword with the Ball class in an attempt to create a Ball object. Because Ball is an abstract class, you can use it to create an object instance.


DESIGN PATTERN

You can create a subclass from an abstract class like this:

public class BaseBall extends Ball
{
public int hit(int batSpeed)
{
// code that implements the hit method goes here
}
}

When you subclass an abstract class, the subclass must provide an implementation for each abstract method in the abstract class. In other words, it must override each abstract method with a non-abstract method. (If it doesn't, the subclass is also abstract, so it too cannot be instantiated.)


Tip

Abstract classes are useful when you want to create a generic type that is used as the superclass for two or more subclasses, but the superclass itself doesn't represent an actual object. For example, if all employees are either salaried or hourly, creating an abstract Employee class makes sense, and then use it as the base class for the SalariedEmployee and HourlyEmployee subclasses.

Here are a few additional points to ponder concerning abstract classes:

  • Not all the methods in an abstract class have to be abstract. A class can provide an implementation for some of its methods but not others. In fact, even if a class doesn't have any abstract methods, you can still declare it as abstract. (In that case, the class can't be instantiated.)


    TECHNICAL STAUFF

    A private method can't be abstract. That only makes sense, because a subclass can't override a private method, and abstract methods must be overridden.

  • Although you can't create an instance of an abstract class, you can declare a variable using an abstract class as its type. Then use the variable to refer to an instance of any of the subclasses of the abstract class.

  • A class can't specify both abstract and final. That would cause one of those logical paradoxes that result in the complete annihilation of the entire universe. Well, hopefully the effect would be localized. But the point is that because an abstract class can only be used if you subclass it, and a final class can't be subclassed, letting you specify both abstract and final for the same class doesn't make sense.


TECHNICAL STAUFF

Abstract classes are used extensively in the Java API. Many of the abstract classes have names that begin with Abstract, such as AbstractBorder, AbstractCollection, and AbstractMap. But most of the abstract classes don't. For example, the InputStream class (used by System.in) is abstract.

Monday, December 15, 2008

Inheritance

Using Subclasses and Inheritance

As you find out in Book III, Chapter 1, a Java class can be based on another class. Then the class becomes like a child to the parent class: It inherits all the characteristics of the parent class, good and bad. All the fields and methods of the parent class are passed on to the child class. The child class can use these fields or methods as is, or it can override them to provide its own versions. In addition, the child class can add fields or methods of its own.

In this chapter, you discover how this magic works, along with the basics of creating and using Java classes that inherit other classes. You also find out a few fancy tricks that help you get the most out of inheritance.

Introducing Inheritance

The word inheritance conjures up several different non-computer meanings:

  • Children inherit certain characteristics from the parents. For example, two of my three children have red hair. (Hopefully, they won't be half bald by the time they're 30.)

  • Children can also inherit behavior from their parents. As they say, the apple doesn't fall far from the tree.

  • When someone dies, their heirs get their stuff. Some of it is good stuff, but some of it may not be. My kids are going to have a great time rummaging through my garage deciding who gets what.

  • You can inherit rights as well as possessions. For example, you may be a citizen of a country by virtue of being born to parents who are citizens of that country.

In Java, inheritance refers to a feature of object-oriented programming that lets you create classes that are derived from other classes. A class that's based on another class is said to inherit the other class. The class that is inherited is called the parent class, the base class, or the superclass. The class that does the inheriting is called the child class, the derived class, or the subclass.


Tip

The terms subclass and superclass seem to be the preferred terms among Java gurus. So if you want to look like you know what you're talking about, use these terms. Also, be aware that the term subclass can be used as a verb. For example, when you create a subclass that inherits a base class, you are subclassing the base class.

You need to know a few important things about inheritance:

  • A derived class automatically takes on all the behavior and attributes of its base class. Thus, if you need to create several different classes to describe types that aren't identical but have many features in common, you can create a base class that defines all the common features. Then you can create several derived classes that inherit the common features.

  • A derived class can add features to the base class it inherits by defining its own methods and fields. This is one way a derived class distinguishes itself from its base class.

  • A derived class can also change the behavior provided by the base class. For example, a base class may provide that all classes derived from it have a method named play, but each class is free to provide its own implementation of the play method. In this case, all classes that extend the base class provide their own implementation of the play method.


  • Tip

    Inheritance is best used to implement is-a-type-of relationships. For example: Solitaire is a type of game; a truck is a type of vehicle; an invoice is a type of transaction. In each case, a particular kind of object is a specific type of a more general category of objects.

The following sections provide some examples that help illustrate these points.

Motorcycles, trains, and automobiles

Inheritance is often explained in terms of real-world objects such as cars and motorcycles, birds and reptiles, or other familiar real-world objects. For example, consider various types of vehicles. Cars and motorcycles are two distinct types of vehicles. If you're writing software that represents vehicles, you could start by creating a class called Vehicle that would describe the features that are common to all types of vehicles-such as wheels, a driver, the ability to carry passengers, and the ability to perform actions such as driving, stopping, turning, or crashing.

A motorcycle is a type of vehicle that further refines the Vehicle class. The Motorcycle class would inherit the Vehicle class, so it would have wheels, a driver, possibly passengers, and the ability to drive, stop, turn, or crash. In addition, it would have features that differentiate it from other types of vehicles. For example, it has two wheels and uses handlebars for steering control.

A car is also a type of vehicle. The Car class would inherit the Vehicle class, so it too would have wheels, a driver, possibly some passengers, and the ability to drive, stop, turn, or crash. Plus it would have some features of its own, such as having four wheels and a steering wheel, seat belts and air bags, and an optional automatic transmission.

Playing games

Because you'll unlikely ever actually write a program that simulates cars, motorcycles, or other vehicles, take a look at a more common example: games. Suppose you want to develop a series of board games such as Life, Sorry!, or Monopoly. Most board games have certain features in common:

  • They have a playing board that has locations that players can occupy.

  • They have players that are represented by objects.

  • The game is played by each player taking a turn, one after the other. Once the game starts, it keeps going until someone wins. (If you don't believe me, ask the kids who tried to stop a game of Jumanji before someone won.)

Each specific type of game has these basic characteristics, but adds features of its own. For example, Life adds features such as money, insurance policies, spouses and children, and a fancy spinner in the middle of the board. Sorry! has cards you draw to determine each move and safety zones within which other players can't attack you. And Monopoly has Chance and Community Chest cards, properties, houses, hotels, and money.

If you were designing classes for these games, you might create a generic BoardGame class that defines the basic features common to all board games, and then use it as the base class for classes that represent specific board games, such as LifeGame, SorryGame, and MonopolyGame.

A businesslike example

If vehicles or games don't make it clear enough, here's an example from the world of business. Suppose you're designing a payroll system and you're working on the classes that represent the employees. You realize that the payroll basically includes two types of employees: salaried employees and hourly employees. So you decide to create two classes, sensibly named SalariedEmployee and HourlyEmployee.

You quickly discover that most of the work done by these two classes is identical. Both types of employees have names, addresses, Social Security numbers, totals for how much they've been paid for the year, how much tax has been withheld, and so on.

However, they have important differences. The most obvious is that the salaried employees have an annual salary and the hourly employees have an hourly pay rate. But there are other differences as well. For example, hourly employees have a schedule that changes week to week. And salaried employees may have a benefit plan that isn't offered to hourly employees.

So you decide to create three classes instead of just two. A class named Employee handles all the features that are common to both types of employees. Then this class is the base class for the SalariedEmployee and HourlyEmployee classes. These classes provide the additional features that distinguish salaried employees from hourly employees.

Inheritance hierarchies

One of the most important aspects of inheritance is that a class derived from a base class can (in turn) be used as the base class for another derived class. Thus you can use inheritance to form a hierarchy of classes.

For example, you've already seen how an Employee class can be used as a base class to create two types of subclasses: a SalariedEmployee class for salaried employees and an HourlyEmployee class for hourly employees. Suppose that salaried employees fall into two categories: management and sales. Then you could use the SalariedEmployee class as the base class for two more classes: Manager and SalesPerson.

Thus a Manager is a type of SalariedEmployee. And because a SalariedEmployee is a type of Employee, a Manager is also a type of Employee.


TECHNICAL STAUFF

All classes ultimately derive from a Java class named Object. Any class that doesn't specifically state what class it is derived from is assumed to derive from the Object class. This class provides some of the basic features that are common to all Java classes, such as the toString method. For more information, see Book III, Chapter 5.

Saturday, December 13, 2008

Statics

Working with Statics

Astatic method is a method that isn't associated with an instance of a class. (Unless you jumped straight to this chapter, you already knew that.) Instead, the method belongs to the class itself. As a result, you can call the method without first creating a class instance. In this chapter, you find out everything you need to know about creating and using static fields and methods.

Understanding Static Fields and Methods

According to my handy Webster's dictionary, the word static has several different meanings. Most of them relate to the idea of being stationary or unchanging. For example, a static display is a display that doesn't move. Static electricity is an electrical charge that doesn't flow. A static design is a design that doesn't change.

The term static as used by Java doesn't mean unchanging. For example, you can create a static field, and then assign values to it as a program executes. Thus the value of the static field can change.

To further confuse things, the word static can also mean interference, as in radio static that prevents you from hearing music clearly on the radio. But in Java, the term static doesn't have anything to do with interference or bad reception.

So what does the term static mean in Java? It's used to describe a special type of field or method that isn't associated with a particular instance of a class. Instead, static fields and methods are associated with the class itself. That means you don't have to create an instance of the class to access a static field or methods. Instead, you access a static field or method by specifying the class name, not a variable that references an object.

Static fields and methods have many common uses. Here are but a few:

  • To provide constants or other values that aren't related to class instances. For example, a Billing class might have a constant named SALES_TAX_RATE that provides the state sales tax rate.

  • To keep a count of how many instances of a class have been created. For example, a Ball class used in a game might have a static field that counts how many balls currently exist. This count doesn't belong to any one instance of the Ball class.

  • In a business application, to keep track of a reference or serial number that's assigned to each new object instance. For example, an Invoice class might maintain a static field that holds the invoice number that is assigned to the next Invoice object created from the class.

  • To provide an alternative way to create instances of the class. An excellent example of this is the NumberFormat class, which has static methods such as getCurrencyInstance and getNumberInstance that return object instances to format numbers in specific ways. One reason you might want to use this technique is to create classes that can have only one object instance. This is called a singleton class, and is described more in the sidebar "The Singleton pattern," which appears later in this chapter.

  • To provide utility functions that aren't associated with an object at all. A good example in the Java API library is the Math class, which provides a bunch of static methods to do math calculations. An example you might code yourself would be a DataValidation class with static methods that validate input data, or a database class with static methods that perform database operations.

Friday, December 12, 2008

Making Classes

Making Your Own Classes

Okay, class, it's time to learn how to create your own classes.

In this chapter, you discover the basics of creating classes in Java. All Java programs are classes, so you've already seen many examples of classes. For example, you've seen class headers such as public class GuessingGame and static methods such as public static void main. Now, in this chapter, I show you how to create programs that have more than one class.

Declaring a Class

All classes must be defined by a class declaration-lines of code that provide the name for the class and the body of the class. Here's the most basic form of a class declaration:

[public] class ClassName { class-body }

The public keyword indicates that this class is available for use by other classes. Although it is optional, you usually include it on your class declarations. After all, the main reason you write class declarations is so other classes can create objects from the class you're defining. (Find out more about using the public keyword in the section "Where classes go" later in this chapter.)


TECHNICAL STAUFF

In later chapters of this book, you find out about some additional elements that can go in a class declaration. The format I'm describing here is just the basic format used to create basic classes.

Picking class names

The ClassName is an identifier that provides a name for your class. You can use any identifier you want to name a class, but the following three guidelines can simplify your life:

  • Begin the class name with a capital letter. If the class name consists of more than one word, capitalize each word. For example, Ball, RetailCustomer, and GuessingGame.

  • Whenever possible, use nouns for your class names. Classes create objects, and nouns are the words you use to identify objects. Thus most class names should be nouns.

  • Avoid using the name of a Java API class. No rule says you absolutely have to, but if you create a class that has the same name as a Java API class, you have to use fully qualified names (such as java.util. Scanner) to tell your class apart from the API class with the same name.


    Tip

    There are literally thousands of Java API classes, so avoiding them all is pretty hard. But at the least, you should avoid commonly used Java class names-as well as any API classes your application is likely to use. For example, creating a class named String or Math is just asking for trouble.

What goes in the class body

The class body of a class is everything that goes within the braces at the end of the class declaration. The public class ClassName part of a class declaration takes just one line, but the body of the class declaration may take hundreds of lines. Or thousands if you get carried away.

The class body can contain the following elements:

  • Fields: Variable declarations define the public or private fields of a class.

  • Methods: Method declarations define the methods of a class.

  • Constructors: A constructor is a block of code that's similar to a method but is run to initialize an object when an instance is created. A constructor must have the same name as the class itself and, although it resembles a method, it doesn't have a return type.

  • Initializers: These are stand-alone blocks of code that are run only once, when the class is initialized. There are actually two types, called static initializers and instance initializers. Although you won't use them often, I talk about instance initializers later in this chapter, in the section "Using Initializers." (For information about static initializers, refer to Book III, Chapter 3.)

  • Other classes and interfaces: A class can include another class, which is then called an inner class or a nested class. Classes can also contain interfaces. (For more information about inner classes, see Book III, Chapter 7. And for information about interfaces, refer to Book III, Chapter 5.)


Tip

Unlike some programming languages, Java doesn't care about the order in which items appear in the class body. Still, being consistent about the order in which you place things in your classes is a good idea. That way you know where to find them. I usually code all the fields together at the start of the class, followed by constructors and then methods. If the class includes initializers, I place them near the fields they initialize. And if the class includes inner classes, I usually place them after the methods that use them.

Some programmers like to place the fields at the end of the class rather than at the beginning. Whatever brings you happiness is fine with me.


TECHNICAL STAUFF

The fields, methods, classes, and interfaces contained within a class are called the members of the class. Constructors and initializers aren't considered to be members, for reasons that are too technical to explain at this point. (You can find the explanation in Book III, Chapter 3.)

Where classes go

A public class must be written in a source file that has the same name as the class, with the extension java. For example, a public class named Greeter must be placed in a file named Greeter.java.

As a result, you can't place two public classes in the same file. For example, the following source file (named DiceGame.java) won't compile:

public class DiceGame
{
public static void main(String[] args)
{
Dice d = new Dice();
d.roll();
}
}

public class Dice
{
public void roll()
{
// code that rolls the dice goes here
}
}

The compiler coughs up a message indicating that Dice is a public class and must be declared in a file named Dice.java.

This problem has two solutions. The first is to remove the public keyword from the Dice class:

public class DiceGame
{
public static void main(String[] args)
{
Dice d = new Dice();
d.roll();
}
}

class Dice
{
public void roll()
{
// code that rolls the dice goes here
}
}

The compiler gladly accepts this program.


Tip

This is not the same thing as an inner class. An inner class is a class that's defined within the body of another class, and is available only from within that class. (For more information about inner classes, see Book III, Chapter 7.)


TECHNICAL STAUFF

When you code more than one class in a single source file, Java still creates a separate class file for each class. Thus, when you compile the DiceGame. java file, the Java compiler creates two class files-named DiceGame.class and Dice.class.

Removing the public keyword from a class is acceptable for relatively small programs. But its limitation is that the Dice class is available only to the classes defined within the DiceGame.java file. If you want the Dice class to be more widely available, opt for the second solution: Place it-with the public keyword-in a separate file named Dice.java.


Tip

If you're going to create an application that has several public classes, create a separate folder for the application. Then, save all the class files for the application to this folder. If you keep your class files together in the same folder, the Java compiler can find them. If you place them in separate folders, you may need to adjust your ClassPath environment variable to help the compiler find the classes.

Thursday, December 11, 2008

Object-Oriented

Understanding Object-Oriented Programming

This chapter is a basic introduction to object-oriented programming. It introduces you to some of the basic concepts and terms you need to know as you get a handle on the specific details of how object-oriented programming works in Java.


Tip

If you're more of a hands-on type, you may want to just skip this chapter and go straight to Book III, Chapter 2, where you find out how to create your own classes in Java. You can always return to this chapter later to review the basic concepts that drive object-oriented programming. Either way is okay by me. I get paid the same whether you read this chapter now or skip it and come back to it later.

What Is Object-Oriented Programming?

The term object-oriented programming means many different things. But at its heart, object-oriented programming is a type of computer programming based on the premise that all programs are essentially computer-based simulations of real-world objects or abstract concepts. For example:

  • Flight-simulator programs attempt to mimic the behavior of real airplanes. Some do an amazingly good job; military and commercial pilots train on them. In the 1960s, the Apollo astronauts used a computer-controlled simulator to practice for their moon landings.

  • Many computer games are simulations of actual games humans play-such as baseball, NASCAR racing, and chess. But even abstract games such as Pac Man or Final Fantasy 4 attempt to model the behavior of creatures and objects that could exist somewhere. Those programs simulate a conceptual game-one that can't actually be played anywhere in the real world but can by simulated by a computer.

  • Business programs can be thought of as simulations of business processes-such as order taking, customer service, shipping, and billing. For example, an invoice isn't just a piece of paper; it's a paper that represents a transaction that has occurred between a company and one of its customers. Thus a computer-based invoice is really just a simulation of that transaction.


TECHNICAL STAUFF

The notion of a programming language having a premise of this sort isn't new. Traditional programming languages such as C (and its predecessors, including even COBOL) are based on the premise that computer programs are computerized implementations of actual procedures-the electronic equivalent of "Step 1: Insert Tab A into Slot B." The LISP programming language is based on the idea that all programming problems can be looked at as different ways of manipulating lists. And the ever-popular database-manipulation language SQL views programming problems as ways to manipulate mathematical sets.

Here are some additional thoughts about the notion of computer programs being simulations of real-world objects or abstract concepts:

  • Sometimes the simulation is better than the real thing. Word-processing programs started out as simulations of typewriters, but a modern word-processing program is far superior to any typewriter.

  • The idea that all computer programs are simulations of one type or another isn't a new one. In fact, the first object-oriented programming language (Simula) was developed in the 1960s. By 1967, this language had many of the features we now consider fundamental to object-oriented programming-including classes, objects, inheritance, and virtual methods.

  • Come to think of it, manual business recordkeeping systems are simulations too. A file cabinet full of printed invoices doesn't hold actual orders. It holds written representations of those orders. A computer is a better simulation device than a file cabinet, but both are simulations.

Wednesday, December 10, 2008

Handling Exceptions

Handling Exceptions

This chapter is about what happens when Java encounters an error situation that it can't deal with. Over the years, computer programming languages have devised many different ways to deal with these types of errors. The earliest programming languages dealt with them rudely, by abruptly terminating the program and printing out the entire contents of the computer's memory in hexadecimal. This output was called a dump.

Later programming languages tried various ways to keep the program running when serious errors occurred. In some languages, the statements that could potentially cause an error had extra elements added to them that would provide feedback about errors. For example, a statement that read data from a disk file might return an error code if an I/O error occurred. Still other languages let you create a special error processing section of the program, to which control would be transferred if an error occurred.

Being an object-oriented programming language, Java handles errors by using special exception objects that are created when an error occurs. In addition, Java has a special statement called the try statement that you must use to deal with exception objects. In this chapter, you find all the gory details of working with exception objects and try statements.

Understanding Exceptions

An exception is an object that's created when an error occurs in a Java program and Java can't automatically fix the error. The exception object contains information about the type of error that occurred. However, the most important information-the cause of the error-is indicated by the name of the exception class used to create the exception. You don't usually have to do anything with an exception object other than figure out which one you have.

Each type of exception that can occur is represented by a different exception class. For example, here are some typical exceptions:

  • IllegalArgumentException: You passed an incorrect argument to a method.

  • InputMismatchException: The console input doesn't match the data type expected by a method of the Scanner class.

  • ArithmeticException: You tried an illegal type of arithmetic operation, such as dividing an integer by zero.

  • IOException: A method that performs I/O encountered an unrecoverable I/O error.

  • ClassNotFoundException: A necessary class couldn't be found.

There are many other types of exceptions besides these. You find out about many of them in later chapters of this book.

You need to know a few other things about exceptions:

  • When an error occurs and an exception object is created, Java is said to have thrown an exception. Java has a pretty good throwing arm, so the exception is always thrown right back to the statement that caused it to be created.

  • The statement that caused the exception can catch the exception if it wants it. But it doesn't have to catch the exception if it doesn't want it. Instead, it can duck and let someone else catch the exception. That someone else is the statement that called the method that's currently executing.

  • If everyone ducks and the exception is never caught by the program, the program ends abruptly and displays a nasty-looking exception message on the console. (More on that in the next section.)

  • Two basic types of exceptions in Java are checked exceptions and unchecked exceptions:

    • A checked exception is an exception that the compiler requires you to provide for it one way or another. If you don't, your program doesn't compile.

    • An unchecked exception is an exception that you can provide for, but you don't have to.

  • So far in this book, I've avoided using any Java API methods that throw checked exceptions. However, I have used methods that can throw unchecked exceptions. For example, the nextInt method of the Scanner class throws an unchecked exception if the user enters something other than a valid integer value. For more information, read on.

Witnessing an exception

Submitted for your approval is a tale of a hastily written Java program, quickly put together to illustrate certain Java programming details while ignoring others. Out of sight, out of mind, as they say. Said program played a guessing game with the user, accepting numeric input via a class called Scanner.

Yet this same program ignored the very real possibility that the user may enter strange and unexpected data, data that could hardly be considered numeric, at least not in the conventional sense. The time: Now. The place: Here. This program is about to cross over into the Exception Zone.

The program I'm talking about here is, of course, the Guessing Game program that's appeared in several forms in recent chapters. (You can find the most recent version at the very end of Book II, Chapter 7.) This program includes a validation routine that prevents the user from making a guess that's not between 1 and 10. However, that validation routine assumes that the user has entered a valid integer number. If the user enters something other than an integer value, the nextInt method of the Scanner class fails badly.

Figure 8-1 shows an example of what the console looks like if the user enters text (such as five) instead of a number. The first line after the user enters the incorrect data says the program has encountered an exception named InputMismatchException. In short, this exception means that the data entered by the user couldn't be properly matched with the type of data that was expected by the Scanner class. That's because the nextInt method expected to find an integer, and instead it found the word five.

Image from book
Figure 8-1: This program has slipped into the Exception Zone.

Finding the culprit

You can find the exact statement in your program that caused the exception to occur by examining the lines that are displayed right after the line that indicates which exception was encountered. These lines, called the stack trace, list the different methods that the exception passed through before your program was completely aborted. Usually the first method listed is deep in the bowels of the Java API, and the last method listed is your application's main method. Somewhere in the middle, you find the switch from methods in the Java API to a method in your program. That's usually where you find the statement in your program that caused the error.

In Figure 8-1, the stack trace lines look like this:

at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at GuessingGameMethod3.getGuess(GuessingGameMethod3.java:51)
at GuessingGameMethod3.playARound(GuessingGameMethod3.java:31)
at GuessingGameMethod3.main(GuessingGameMethod3.java:13)

Each line lists not only a class and method name, but also the name of the source file that contains the class and the line number where the exception occurred. Thus the first line in this stack trace indicates that the exception is handled in the throwFor method of the Scanner class at line 819 of the Scanner.java file. The next three lines also indicate methods in the Scanner class. The first line to mention the GuessingGame class (GuessingGameMethod3) is the fifth line. It shows that the exception happened at line 51 in the GuessingGameMethod3.java file. Sure enough, that's the line that calls the nextInt method of the Scanner class to get input from the user.