Next page | Contents page |

Methods inherited from Object

Summary of the methods inherited by all classes

We will now look at how to override the first 4 of those.

String toString ()

Should provide a summary of the state of the object, derived from the values of its fields - all of them, or the most important ones if there are very many. In the case of object fields call their toString () methods, assuming they have been overridden (programmers too often skip it though).

Very useful for debugging.

public class X extends Y
{
   int i;  String s; // ... and other data

   @Override
   public String toString ()
   {
      return super.toString () + "; " + i + "; " + s;
		// ... and all other data.toString ()
		// if that is what you want as a string
		// representation of the object.
   }

   //... rest of class definition
  

boolean equals (Object b)

If you ever want to test whether 2 objects are identical (not just the same reference) you need to override this method. Some people say you really must always override it for every class you ever write. You certainly must override it for any class whose objects may be used as hash keys. It is also important for unit testing - how else will you test whether the expected result of a method under test is equal to the actual result?

There are some subtleties to beware of though, so again programmers are tempted to skip overriding this method.

public class MyClass
{
	@Override
	public boolean equals (Object another)
	{
		if (null == another) return false; 
		if (!getClass().equals (another.getClass())) return false;

		MyClass other = (MyClass) another; // Now safe to cast
		if (field1primitive != other.field1primitive) return false; 
		if (!field2object.equals (other.field2object)) return false;
		// ... for all fields
		return true; // All tests passed
	} // equals

Notice a few things here:

int hashCode ()

The inherited version returns an integer based on the reference of the object, nothing to do with its contents.

Overridden in String (but not StringBuffer) to make a useful value from the text of the string.

You must override for any class whose objects will be used as keys for a hash table (java.util.HashMap, etc). The point of a hash table is to be able to look up an object directly from its contents, without searching. We will see how that works soon.

public class MyClass
{
	@Override
	public int hashCode ()
	{
		return 7 * field1.hashCode () + 13 * field2.hashCode () + field3; 
		// ... (say field3 happens to be an int)
	} // hashCode

People use prime numbers as multipliers here to try to reduce the chances of two objects ending up with the same hash code. I am not sure whether there is any true mathematical basis for this.

You must use all the same fields you used in your overridden equals () method, to ensure that a.equals (b) always implies a.hashCode () == b.hashCode ().

Object clone ()

public class Person implements Cloneable
{
	private String name;

	@Override
	public Object clone ()
	{ 
		try
		{
			// Always clone the superclass first, in this case Object:
			Person copy = (Person) super.clone ();
			// Then copy the fields of this class, using their clone()
			// or perhaps a constructor:
			copy.name = new String (name);
			return copy;
		}
		catch (CloneNotSupportedException ex)
		{  
			throw new Error ("Should never occur!"); 
		}
	} // clone

java.lang.Cloneable is a marker interface, showing that our class has overridden clone (). Marker interfaces have no methods for us to implement.

Next page | Contents page |