Book Home Java Enterprise in a Nutshell Search this book

2.8. Classes and Objects

Now that we have introduced operators, expressions, statements, and methods, we can finally talk about classes. A class is a named collection of fields that hold data values and methods that operate on those values. Some classes also contain nested inner classes. Classes are the most fundamental structural element of all Java programs. You cannot write Java code without defining a class. All Java statements appear within methods, and all methods are defined within classes.

Classes are more than just another structural level of Java syntax. Just as a cell is the smallest unit of life that can survive and reproduce on its own, a class is the smallest unit of Java code that can stand alone. The Java compiler and interpreter do not recognize fragments of Java code that are smaller than a class. A class is the basic unit of execution for Java, which makes classes very important. Java actually defines another construct, called an interface, that is quite similar to a class. The distinction between classes and interfaces will become clear in Chapter 3, "Object-Oriented Programming in Java", but for now I'll use the term "class" to mean either a class or an interface.

Classes are important for another reason: every class defines a new data type. For example, you can define a class named Point to represent a data point in the two-dimensional Cartesian coordinate system. This class can define fields (each of type double) to hold the X and Y coordinates of a point and methods to manipulate and operate on the point. The Point class is a new data type.

When discussing data types, it is important to distinguish between the data type itself and the values the data type represents. char is a data type: it represents Unicode characters. But a char value represents a single specific character. A class is a data type; the value of a class type is called an object. We use the name class because each class defines a type (or kind, or species, or class) of objects. The Point class is a data type that represents X,Y points, while a Point object represents a single specific X,Y point. As you might imagine, classes and their objects are closely linked. In the sections that follow, we will be discussing both.

2.8.1. Defining a Class

Here is a possible definition of the Point class we have been discussing:

/** Represents a Cartesian (x,y) point */
public class Point {
  public double x, y;                    // The coordinates of the point. 
  public Point(double x, double y) {     // A constructor that
    this.x = x; this.y = y;              // initializes the fields. 
  }

  public double distanceFromOrigin() {   // A method that operates on
    return Math.sqrt(x*x + y*y);         // the x and y fields. 
  }
}

This class definition is stored in a file named Point.java and compiled to a file named Point.class, at which point it is available for use by Java programs and other classes. This class definition is provided here for completeness and to provide context, but don't expect to understand all the details just yet; most of Chapter 3, "Object-Oriented Programming in Java" is devoted to the topic of defining classes. Do pay extra attention to the first (non-comment) line of the class definition, however. Just as the first line of a method definition--the method signature--defines the API for the method, this line defines the basic API for a class (as described in the next chapter).

Keep in mind that you don't have to define every class you want to use in a Java program. The Java platform consists of over 1500 predefined classes that are guaranteed to be available on every computer that runs Java.

2.8.2. Creating an Object

Now that we have defined the Point class as a new data type, we can use the following line to declare a variable that holds a Point object:

Point p;

Declaring a variable to hold a Point object does not create the object itself, however. To actually create an object, you must use the new operator. This keyword is followed by the object's class (i.e., its type) and an optional argument list in parentheses. These arguments are passed to the constructor method for the class, which initializes internal fields in the new object:

// Create a Point object representing (2,-3.5) and store it in variable p
Point p = new Point(2.0, -3.5);

// Create some other objects as well
Date d = new Date();         // A Date object that represents the current time
Vector list = new Vector();  // A Vector object to hold a list of objects

The new keyword is by far the most common way to create objects in Java. There are a few other ways that are worth mentioning, however. First, there are a couple of classes that are so important that the Java language defines special literal syntax for creating objects of those types (as we'll discuss in the next section). Second, Java supports a dynamic loading mechanism that allows programs to load classes and create instances of those classes dynamically. This dynamic instantiation is done with the newInstance() methods of java.lang.Class and java.lang.Constructor. Finally, in Java 1.1 and later, objects can also be created by deserializing them. In other words, an object that has had its state saved, or serialized, usually to a file, can be recreated using the java.io.ObjectInputStream class.

2.8.3. Object Literals

As I just said, Java defines special syntax for creating instances of two very important classes. The first class is String, which represents text as a string of characters. Since programs usually communicate with their users through the written word, the ability to manipulate strings of text is quite important in any programming language. In some languages, strings are a primitive type, on a par with integers and characters. In Java, however, strings are objects; the data type used to represent text is the String class.

Because strings are such a fundamental data type, Java allows you to include text literally in programs by placing it between double-quote (") characters. For example:

String name = "David";
System.out.println("Hello, " + name);

Don't confuse the double-quote characters that surround string literals with the single-quote (or apostrophe) characters that surround char literals. String literals can contain any of the escape sequences char literals can (see Table 2-3). Escape sequences are particularly useful for embedding double-quote characters within double-quoted string literals. For example:

String story = "\t\"How can you stand it?\" he asked sarcastically.\n";

String literals can be only a single line long. Java does not support any kind of continuation-character syntax that allows two separate lines to be treated as a single line. If you need to represent a long string of text that does not fit on a single line, break it into independent string literals and use the + operator to concatenate the literals. For example:

String s = "This is a test of the         // This is illegal; string literals
            emergency broadcast system";  // cannot be broken across lines. 

String s = "This is a test of the " +     // Do this instead. 
           "emergency broadcast system";

This concatenation of literals is done when your program is compiled, not when it is run, so you do not need to worry about any kind of performance penalty.

The second class that supports its own special object literal syntax is the class named Class. Class is a (self-referential) data type that represents all Java data types, including primitive types and array types, not just class types. To include a Class object literally in a Java program, follow the name of any data type with .class. For example:

Class typeInt = int.type;
Class typeIntArray = int[].type;
Class typePoint = Point.class;

This feature is supported by Java 1.1 and later.

The Java reserved word null is a special literal that can be used with any class. Instead of representing a literal object, it represents the absence of an object. For example:

String s = null;
Point p = null;

Finally, objects can also be included literally in a Java program through the use of a construct known as an anonymous inner class. Anonymous classes are discussed in Chapter 3, "Object-Oriented Programming in Java".

2.8.4. Using an Object

Now that we've seen how to define classes and instantiate them by creating objects, we need to look at the Java syntax that allows us to use those objects. Recall that a class defines a collection of fields and methods. Each object has its own copies of those fields and has access to those methods. We use the dot character (.) to access the named fields and methods of an object. For example:

Point p = new Point(2, 3);         // Create an object
double x = p.x;                    // Read a field of the object 
p.y = p.x * p.x;                   // Set the value of a field 
double d = p.distanceFromOrigin(); // Access a method of the object

This syntax is central to object-oriented programming in Java, so you'll see it a lot. Note, in particular, the expression p.distanceFromOrigin(). This tells the Java compiler to look up a method named distanceFromOrigin() defined by the class Point and use that method to perform a computation on the fields of the object p. We'll cover the details of this operation in Chapter 3, "Object-Oriented Programming in Java".



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.