// this code demonstrates the concepts of copying the class reference and the
// class

public class CopyClass
{
  public static void main(String[] args)
  {
   // copying the reference won't actually copy the class
     CopyClassTest c1 = new CopyClassTest(1, "test");
     CopyClassTest c2 = c1; 
     System.out.println("after copying the reference:");   
     System.out.println("c1: " + c1);
     System.out.println("c2: " + c2);
     System.out.println("c1=c2 is " + c1.equals(c2));
     
     System.out.println("after modification of c2:");
     c2.modifyIt(100, "bbb");   // "both c1 and c2" will be modified
     System.out.println("c1: " + c1);
     System.out.println("c2: " + c2);
     System.out.println("c1=c2 is " + c1.equals(c2) + "\n");

   // now c1 and c2 will point to two different instances of the class   
     c2 = new CopyClassTest(c1);  
     System.out.println("after making a copy c2 of c1:");
     System.out.println("c1: " + c1);
     System.out.println("c2: " + c2);
     System.out.println("c1=c2 is " + c1.equals(c2));

     c2.modifyIt(1000, "ccc");
     System.out.println("after modification of c2:");
     System.out.println("c1: " + c1);
     System.out.println("c2: " + c2);
     System.out.println("c1=c2 is " + c1.equals(c2));
  }
}

class CopyClassTest 
{
  private int a;
  private String s;

  public CopyClassTest(int a, String s)   // a constructor with 2 params
  {
    this.a = a;
    this.s = s;
  }

  public CopyClassTest()                  // the default constructor
  {
    a = 2;
    s = "aaa";
  }

  public CopyClassTest(CopyClassTest o)   // the copy constructor
  {
    a = o.a;                              // even private class members can 
    s = o.s;                              // be accessed directly in the 
  }                                       // copy constructor

  public void modifyIt(int a, String s)
  {
    this.a = a;
    this.s = s;
  }

  public String toString()                 // overloading of toString()
  {
    return a + " " + s;
  }

  public boolean equals(CopyClassTest o)   // overloading of equals()
  {
     return (a == o.a && s.equals(o.s));
  }
}
