0

I have written one test app, to demonstrate Java clone using Shallow, Deep and Copy constructor.

I achieved with Shallow and Deep but with Copy constructor I think I am missing something.

Please look in a code below and let me know the fix for Copy constructor implementation.

public class CopyConstructorDemo {

    public static void main(String[] args) {

        Teacher teacher = new Teacher("Kripalu");
        Student sOrg = new Student(15007, "Amit", "Chirimiri", teacher);

        //Student sClo = sOrg;                          //Java Reference

        //Student sClo = (Student) sOrg.clone();        //CLONE


        Student sClo = new Student(sOrg);               //COPY CONSTRUCTOR

        sOrg.display();

        sClo.getTeacher().setName("ShriKrishn");

        sOrg.display();

    }


}

class Teacher implements Cloneable{

    String _name = "";

    Teacher(String name){
        this.setName(name);
    }

    String getName(){return _name;}
    void setName(String name){_name = name;}

    //For Deep copy
    //@Override
    protected Object clone(){

        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }

    }   
}

class Student implements Cloneable{

    int _rollNo;
    String _name;
    String _address;

    Teacher _teacher;

    Student(int rollNo, String name, String address, Teacher teacher){
        this.setRollNo(rollNo);
        this.setName(name);
        this.setAddress(address);

        _teacher = teacher;
    }

    Student(Student copyCons){
        this._rollNo = copyCons._rollNo;
        this._name = copyCons._name;
        this._address = copyCons._address;
        this._teacher = copyCons._teacher;

    }

    Teacher getTeacher(){return _teacher;}
    void setTeacher(Teacher teacher){_teacher = teacher;}

    int getRollNo(){return _rollNo;}
    String getName(){return _name;}
    String getAddress(){return _address;}

    void setRollNo(int rollNo){_rollNo = rollNo;}
    void setName(String name){_name = name;}
    void setAddress(String address){_address = address;}

    void display(){
        System.out.println(_rollNo+" "+
                           _name+" "+
                           _address+" "+
                           _teacher.getName());
    }

    @Override
    protected Object clone(){

        try {

            //return super.clone();     //For Shallow copy

            //For Deep copy
            Student cloned = (Student)super.clone();
            cloned.setTeacher((Teacher)cloned.getTeacher().clone());
            return cloned;

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }

    }



}

Output (Copy constructor)

15007 Amit Chirimiri Kripalu

15007 Amit Chirimiri ShriKrishn

EDIT:

Since Student class contain Nested class (Teacher) Reference, simple copy constructor will not work. We must use cloning (shallow copy) for Teacher together with Copy constructor of Student class and here is changed copy constructor

Student(Student copyCons){

    this._rollNo = copyCons._rollNo;
    this._name = copyCons._name;
    this._address = copyCons._address;
    this._teacher = (Teacher) copyCons._teacher.clone();  //FIX: thanks to Amir

}

Rest of the code is same.

Amit Yadav
  • 32,664
  • 6
  • 42
  • 57

1 Answers1

2

That's how the copy constructor and the clone method should be:

For the student:

 //Copy constructor for the student
 Student(Student copyCons){
    this._rollNo = copyCons._rollNo;
    this._name = copyCons._name;
    this._address = copyCons._address;
    this._teacher = copyCons._teacher.clone();
}

 //Clone for the student
 protected Student clone(){
     return new Student(this);
 }

For the teacher:

//This is the copy constructor
Teacher(Teacher t){
        setName(t.getName());
 }

//That's how you clone an object of type teacher
protected Teacher clone(){
   return new Teacher(this);
}

Example of use:

Teacher t1 =  new teacher("Teacher 1");
Teacher t1Clone = t1.clone();

Student s1 = new Student(15007, "Amit", "Chirimiri", t1);
Student s1Clone = s1.clone();
CMPS
  • 7,733
  • 4
  • 28
  • 53
  • 1
    Your clone method is allowed to have a Student as return type. You should do this to avoid that cast – MTilsted Apr 13 '14 at 19:13
  • \@Amir, Sorry but I am not getting your code. As i already mentioned that i have achieved with cloning now i have to achieve with copy constructor for Student i have written Copy constructor and using it new Student(org) now what about Teacher can u share me code snip and also how i use it mean where i would call new Teacher(org)....i don't know – Amit Yadav Apr 13 '14 at 19:22
  • 1
    @AmitYadav Take a look at [this question](http://stackoverflow.com/questions/10607990/how-should-i-copy-strings-in-java) and see if that helps you understand what AmirBawab is talking about. – imtheman Apr 13 '14 at 19:53