/**
 *默认得克隆方法为浅克隆只克隆对象得非引用类型(或者非对象型)成员
 *要做深克隆有两种方法:
 *a.覆写克隆方法(引用型成员的克隆方法)并且克隆时掉一次引用型成员的克隆方法!
 *b.序列化对象时默认为深克隆
 *
 */
 
 class Friend implements Cloneable {
   int age;
   String name;
  
  public Friend(int age, String name) {
   this.age = age;
   this.name = name; 
  }
  
  public Object clone () throws CloneNotSupportedException {
   return super.clone(); 
  }
   
 }
 
 class Person implements Cloneable  {
   int age;
  /* *
   *String 类型特殊,因为他为引用型,而且他指向的值为常量,克隆出来的对象改变他的
   *值实际上是改变了克隆出来对象String类型成员的指向不会影响被克隆对象的值及其指向?
   *因为引用被克隆了,我改变的是引用的指向!
  */
   String name;
  
   Friend f;
  
  public Person(int age, String name, Friend f) {
   this.age = age;
   this.name = name;
   this.f = f;
  }
  
  public Object clone () throws CloneNotSupportedException {
   Person p = (Person)super.clone();
   p.f = (Friend)p.f.clone();
   return p; 
  }
  
  public String toString(){
  StringBuffer sb = new StringBuffer();
  return super.toString()+sb.append("age=").append(age).
   append(",name=").append(name).
   append("friend=").append("f.name=").
   append(f.name).append("f.age=").append(f.age).toString();
 }
 }
 
 
 public class Clonetest {
  public static void main(String [] args)  throws CloneNotSupportedException {
   Person p = new Person(4,"haha",new Friend(5,"hehe"));
   Person p1 = (Person)p.clone();
   p1.name = "oop";
   p1.age = 10;
   p1.f.name = "ooad";
   p1.f.age = 56;
   System.out.println (p);
  System.out.println (p1);
  } 
 }