/**
 * A mutable number.
 * <p>
 * [Note on "compatibility":  (You may skip this section on first reading.)
 * <p>
 * Given the level of abstraction enforced by
 * the <code>MyNumber</code> interface, is it reasonable to expect
 * a class's <code>MyNumber</code>-accepting methods to be able to handle
 * <em>arbitrary</em> <code>MyNumber</code>s?
 * For example...
 *
 * <pre>   MyNumber  m = new MyInteger(2);
 *   MyNumber  n = new MyObscureInteger(3);
 *
 *   m.plus(n);  // ...what should happen?</pre>
 *
 * Doesn't it seem a bit unfair to expect the author
 * <code>MyInteger</code> to know how to deal with
 * <code>MyObscureInteger</code>?  [Especially since the latter class might
 * not have even existed when <code>MyInteger</code> was written.]
 * <p>
 * To give <code>MyInteger</code>'s author a way out of this fix, we introduce
 * a notion of "compatibility" between <code>MyNumber</code> classes...
 * Suppose that <code>N1</code> and <code>N2</code> are two
 * classes that both implement <code>MyNumber</code>.  If <code>N1</code>'s
 * <code>MyNumber</code>-accepting methods can always handle instances of
 * <code>N2</code>, and likewise if <code>N2</code>'s
 * <code>MyNumber</code>-accepting methods can always handle instances of
 * <code>N1</code>, then <code>N1</code> and <code>N2</code> are said to be
 * "compatible."
 * Also, as you might expect, if <code>n1</code> is an instance of class <code>N1</code>
 * and <code>n2</code> is an instance of class <code>N2</code>, then
 * "<code>n1</code> is compatible with <code>n2</code>" is equivalent to
 * saying "<code>N1</code> is compatible with <code>N2</code>."
 * <p>
 * At a minimum, a class <code>N</code> that implements <code>MyNumber</code>
 * must be compatible with itself.  In fact, <code>N</code> is typically
 * the only class that is compatible with <code>N</code>.
 * <p>
 * Thus, the author of <code>MyInteger</code> can simply proclaim,
 * "<code>MyInteger</code> is compatible only with itself!"  He is
 * then free to ignore <code>MyObscureInteger</code>, since the behavior
 * of the <code>m.plus(n)</code> line above is officially undefined...]
 * <p>
 * [If Java supported a <code>ThisType</code> mechanism, we could cleanly sidestep
 * the entire "compatibility" morass.  With <code>ThisType</code> at our disposal,
 * we could simply say...
 *
 * <pre>   public void plus(ThisType n);
 *   public ThisType squareOf();
 *   // etc.</pre>
 *
 * ...since <code>ThisType</code> essentially means "the same class as
 * <code>this</code>."]
 * <p>
 * [Note that the compatibility issue is not peculiar to <code>MyNumber</code>;
 * the same basic problem surfaces in the standard
 * <code>java.lang.Comparable</code> interface, for example.]
 * <p>
 * [What methods might you add to <code>MyNumber</code>, if you were
 * interested in requiring <em>all</em> <code>MyNumber</code>s to
 * be compatible?]
 *
 * @author   CS211 Staff
 * @version  0.9.1, 09/14/2000
 */

interface MyNumber {
  /**
   * Returns <code>true</code> if <code>this</code> is smaller than
   * <code>n</code>.
   * <p>
   * [The behavior of the <code>lessThan</code> method is undefined if
   * <code>n</code> is not compatible with <code>this</code>.]
   *
   * @param   n  the number to compare against <code>this</code>
   * @return  <code>true</code> if <code>this</code> is less than
   *          <code>n</code>; <code>false</code> otherwise
   */
  boolean lessThan(MyNumber n);

  /**
   * Replaces <code>this</code> with <code>this + n</code>.
   * <p>
   * [The behavior of the <code>plus</code> method is undefined if
   * <code>n</code> is not compatible with <code>this</code>.]
   *
   * @param  n  the number to be added to <code>this</code>
   */
  void  plus(MyNumber n);

  /**
   * Replaces <code>this</code> with <code>this * n</code>.
   * <p>
   * [The behavior of the <code>times</code> method is undefined if
   * <code>n</code> is not compatible with <code>this</code>.]
   *
   * @param  n  the number by which <code>this</code>
   *            is to be scaled
   */
  void times(MyNumber n);

  /**  
   * Replaces <code>this</code> with <code>-this</code>.
   */
  void minus();

  /**
   * Returns a new object holding the square of the value of
   * <code>this</code>.
   * <p>
   * [The returned object is guaranteed to be an instance of
   * <code>this</code>'s class.]
   *
   * @return  a new <code>MyNumber</code> object (of the same class
   *          as <code>this</code>) that initially stores the
   *          square of this object's integer value.
   */
  MyNumber squareOf();

  /**
   * Returns a new <code>MyNumber</code> object that initially holds
   * the value <code>i</code>.
   * <p>
   * [The returned object is guaranteed to be an instance of
   * <code>this</code>'s class.]
   * <p>
   * Example:
   * <pre>   // construct n...
   *   MyNumber n   = new MyInteger(3);
   *
   *   // increment n...
   *   MyNumber one = n.createCompatible(1);  // ...one is a MyInteger.
   *   n.plus(one);</pre>
   *
   * [The behavior of the <code>createCompatible</code> method is
   * undefined if <code>i</code> is too large (or too small) to be
   * handled by <code>this</code>'s variety of number.]
   *
   * @return  a new <code>MyNumber</code> (of the same class as
   *          <code>this</code>) that takes <code>i</code> as its
   *          initial stored value
   */
  MyNumber createCompatible(int i);

  /*
   *
   * [the following methods, which are declared in Object, are included
   *  here only so that we may attach comments that specify additional
   *  constraints on the methods' behavior.  (in a more advanced type system,
   *  such as nuprl, we would refine the method definitions themselves.)]
   *
   */

  /**
   * Returns a new <code>MyNumber</code> object that initially
   * equals <code>this</code>.
   * <p>
   * [The returned object is guaranteed to be an instance of
   * <code>this</code>'s class.]
   *
   * @return  a new <code>MyNumber</code> (of the same class as
   *          <code>this</code>) that takes <code>this</code>'s
   *          integer value as its initial stored value
   */
  Object clone();
    // ...why not declare the return type to be MyNumber?

  /**
   * Tests whether <code>o</code> and <code>this</code> are equal.
   *
   * @param   o the object to compare against <code>this</code>
   * @return  <code>true</code> if (1) <code>o</code> is a <code>MyNumber</code>
   *          that is compatible with <code>this</code> and (2) <code>o</code>
   *          and <code>this</code> currently store the same integer value;
   *          <code>false</code> otherwise
   */
  boolean equals(Object o);

  /**
   * Retrieves the decimal representation of the stored integer.
   *
   * @return  a <code>String</code> that represents the stored integer,
   *          in decimal
   */
  public String toString();

  // ...we'll ignore hashCode, for now...
}
