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.

No comments:

Post a Comment