A Class Designer's Checklist for Java

Steven Zeil

Last modified: Apr 08, 2014

Contents:
1. The Checklist
2. Discussion and Explanation
2.1 Preconditions and Assertions
2.2 Does your class contain a clone() function?
2.3 equals() and hashCode()
2.4 toString()

1. The Checklist

  1. Is the interface complete?

  2. Are there redundant functions in the interface that could be removed? Are there functions that could be generalized?

  3. Have you used names that are meaningful in the application area?

  4. Are pre-conditions and assumptions well documented?

  5. Are the data members private?

  6. Does every constructor initialize every data member?

  7. Does your class provide a clone() function?

  8. Does your class provide equals() and hashCode() functions?

  9. Does your class provide a toString() function?

2. Discussion and Explanation

Same as in C++

  1. Is the interface complete?
  2. Are there redundant functions or functions that can be generalized?
  3. Have you used names that are meaningful in the application domain?

2.1 Preconditions and Assertions

A pre-condition is a condition that the person calling a function must be sure is true, before the call, if he/she expects the function to do anything reasonable.


Assert Example

public class Day
{
   /**
      Represents a day with a given year, month, and day
      of the Gregorian calendar. The Gregorian calendar
      replaced the Julian calendar beginning on
      October 15, 1582
   */


  public Day(int aYear, int aMonth, int aDate)
  //pre: (aMonth > 0 && aMonth <= 12)
  //  && (aDate > 0 && aDate <= daysInMonth(aMonth,aYear))
  {
    assert (aMonth > 0 && aMonth <= 12); 
    assert (aDate > 0 && aDate <= 31);
    assert (aYear > 1582 || (aYear == 1582 && aMonth > 10)
            || (aYear == 1582 && aMonth == 10 && aDate >= 15));
    ⋮
  } 


Also Same as in C++

2.2 Does your class contain a clone() function?

Useful in C++, even more so in Java.


class C {
   ⋮
  public Object clone() {...}
   ⋮
}

Expression.java

Value.java

NumericValue.java


Contra-Variant Inheritance

We’ve talked before about how parameter types in C++ and Java) do not change when we inherit:

class Base {
     ⋮
   public void compareTo (Base b) { ...
     ⋮
class C extends Base {

   public void compareTo (Base b) { ...

but not

   public void compareTo (C b) { ...


Co-Variant Return Type

An option exception in both languages is for return types:

class Object {
    ⋮
  protected Object clone { ...}
    ⋮
}

class Value implements Cloneable {
    ⋮
  public Value clone { ...}
    ⋮

class NumericValue extends Value {
    ⋮
  public NumericValue clone { ...}
    ⋮
    

Why Use Co-Variant Return Types?

void foo (NumericValue n1)
{
   NumericValue n2 = n1.clone();
   // instead of
   NumericValue n3 = (NumericValue)n1.clone();
   

2.3 equals() and hashCode()

Does your class provide equals() and hashCode() functions?

Just as C++ libraries assume the availability of == and < to support many data structures, Java libraries assume equals() and hashCode()


equals() example

public class Book {
  public Book ()
    {
      authorName = new String();
      title = new String();
    }
 
  public String getAuthorName() {return authorName;}
  public void   setAuthorName(String a) {authorName = a;}
 
  public String getTitle() {return title;}
  public void   setTitle(String t) {title = t;}
 
    public boolean equals(Object right) {
     Book b = (Book)right;
     return authorName.equals(b.authorName) &&
       title.equals(b.title);
  }

  private String authorName;
  private String title;

}



hashCode()


Hashing 101

hashing function

In an ideal world…

If we had a really good hashing function, we could implement table insertion and searching this way:


class set {
  ⋮
  private Object[] table = ...;

  void insert (Object key)
  {
    int h = key.hashCode() % table.length;
    table[h] = key;
  }

  Object get (Object key)
  {
    int h = key.hashCode() % table.length;
    if (table[h].equals(key))
      return table[h];
    else
      return null;
  } 


Collisions


hashCode() Example

bookhash.java

2.4 toString()

Does your class provide a toString() function?

The toString() function is used to convert an object to a String

Example:

bookToString.java