Incremental Java
Object: The Mother of All Classes

All The Way Up

Even if you don't extend a class, you are extending a class. Every class that doesn't extend a class actually extends Object.

If you do extend a class, then Object is the ancestor of that class (and yours).

This means that for any object type you can do:

  Object obj = new Foo() ;
Foo() can be replaced with any other object type (primitive types don't work).

Of course, you can only call Object methods on obj, and there aren't many useful Object methods.

Other OO languages, e.g., C++, do not have a "mother of all classes" like Java does. The reason Java has an Object class is to create container classes and to allow methods that accept any object.

equals

One method that Object has is equals(). Here's the method signature:
public boolean equals( Object o ) ;
This method is meant to check if two objects are equal where the class designer gets to decide what "equals" means. By default, it uses ==, which checks for handle equality (does the object referred to by this have the same handle as the object referred to be o, the parameter variable?)

Common Mistakes

When you override a method, you must keep the same method signature, otherwise you aren't overriding.

A common mistake is to make equals() take a parameter of the same type as the class. For example, suppose you were defining the Foo class.

public class Foo 
{
   // NO! equals must have an Object type as parameter    
   public boolean equals( Foo foo ) 
   {
      // CODE HERE
   }
}
In the example above equals() does not have the correct parameter list, as defined by Object, which insists it must be Object.

We'll talk more about writing equals() later on.

Container Classes

We know objects are containers for instance variables. However, the number of instance variables is fixed at compile time. You can't decide to increase or decrease the number of instance variables while the program is running.

What if you would like to have an object that could hold as many objects as you wanted? Initially, it holds zero objects. Later on, you add ten objects, then maybe ten more. But you don't know the type of the objects ahead of time. You want to hold objects of many different types.

A container class is just such a class. In order to hold objects of many different type, we must make the type that it holds Object. Since every object type is derived from Object, an Object variable (or many such variables) can hold a handle to an object of any type.

We'll talk about container classes later on as well.