Reference vs. Copy Semantics

Literal vs. Logical Equality

Implementing equals()

class Point implements Cloneable, Serializable {
   private double xc = 0; // x coordinate
   private double yc = 0; // y coordinate
   // constructors:
   public Point(double xc, double yc) {
      this.xc = xc;
      this.yc = yc;
   }
   public Point() { this(0, 0); }
   // getters, but no setters:
   public double getXC() { return xc; }
   public double getYC() { return yc; }
   // printers:
   public String toString() {
      return "(" + xc + ", " + yc + ")";
   }
   public boolean equals(Object other) {
      if (other == null) return false;
      //if (! other instanceOf Point) return false;
      Class c1 = other.getClass();
      Class c2 = getClass(); // c2 = "Point"
      if (!c1.equals(c2)) return false;
      Point p = (Point) other;
      return xc == p.xc && yc == p.yc;
   }
   public int hashCode() {
      //return 2;
      return toString().hashCode();
   }

   public Object clone() throws CloneNotSupported {
      return super.clone();
   }
   // etc.
}

class LineSegment implements Cloneable, Serializable {
   private Point start, end;
   // logical equality for line segments:
   public boolean equals(Object other) {
      if (other == null) return false;
      Class c1 = other.getClass();
      Class c2 = getClass(); // c2 = "LineSegment"
      if (!c1.equals(c2)) return false;
      LineSegment ls = (LineSegment) other;
      return start.equals(ls.start) && end.equals(ls.end);
   }

   public Object clone() throws CloneNotSupported {
      //return super.clone();
      // make a deep copy instead:
      LineSegment ls = (LineSegment)super.clone();
      ls.start = (Point)start.clone();
      ls.end = (Point)end.clone();
      return ls;
   }

   // etc.
}

 

Should logical equality imply literal equality?

Synchronization Issues

Factories and Interning

Clonable Objects

Deep vs Shallow Copies

Mutable vs. Non-Mutable Objects

public class AccountManager {
   private Map accounts = new hashtable();
   private static int nextOID = 500;
   public int makeAccount() {
      int oid = nextOID++;
      accounts.put(new Integer(oid), new Account());
      return oid;
   }
   void deposit(Integer oid, double amt) {
      if (authorized()) {
         Account a = (Account)accounts.get(oid);
         a.deposit(amt);
      }
   }
   private boolean authorized() {
      // check id, pin, etc.
   }

private class Holder {   }
private class Account {
   private balance = 0;
   public void deposit(double amt) { balance += amt; }
   public void withdraw(double amt) {
      if (amt <= balance) balance -= amt;
   }
   public double getBalance() { return balance; }
   // etc.
}

}