Previously:    How to make a (true) copy of an object

  • Steps used to make a copy of an object:

        public static void main(String[] args) 
        {
            Circle circle1 = new Circle(4);
          
            // Make a COPY of circle1
            Circle circle2 = new Circle();   // (1) Create a new Circle obj
            circle2.radius = circle1.radius; // (2) Copy the properties over
        } 

Unfortunately... this only works when we access the member variable(s)...

What is the problem ?

This solution will only work when all instance variables in the class are public:

public class Circle
{
    public double radius = 1;       /** The radius of this circle */

    public Circle() { }             /** Constructor 1 for a circle object */

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;
    }

    public double getArea()      /** Return the area of this circle */
    {
        return 3.14159 * radius * radius;
    }

    public void setRadius(double newRadius) /** Set new radius for this circle */
    {
       radius = newRadius;
    }
}  

What is the problem ?

Instance variables in classes are often private because we want data field encapsulation (discussed later):

public class Circle
{
    private double radius = 1;       /** The radius of this circle */

    public Circle() { }             /** Constructor 1 for a circle object */

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;
    }

    public double getArea()      /** Return the area of this circle */
    {
        return 3.14159 * radius * radius;
    }

    public void setRadius(double newRadius) /** Set new radius for this circle */
    {
       radius = newRadius;
    }
}  

DEMO: demo/03-classes/11-copy ---- compile error...

What is the solution ???

Solution:   define a "copy" constructor in the class

The "copy" constructor is a constructor that has a object variable of the classname as parameter:

public class Circle
{
    private double radius = 1;       /** The radius of this circle */

    public Circle() { }             /** Constructor 1 for a circle object */

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;
    }

    public Circle(Circle c)         /** Constructor 3: copies Circle c */
    {
        radius = ????????;  // What should we do here ?
    }

    public double getArea()      /** Return the area of this circle */
    ..
    public void setRadius(double newRadius) /** Set new radius for this circle */
    ..
}  

The "copy" constructor will copy all the instance variables from its input parameter to the new object... how ??

Solution:   define a "copy" constructor in the class

To copy the instance variables, use assignment:

public class Circle
{
    private double radius = 1;       /** The radius of this circle */

    public Circle() { }             /** Constructor 1 for a circle object */

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;
    }

    public Circle(Circle c)         /** Constructor 3: copies circle c */
    {
        radius = c.radius;  // Copies c.radius to radius of new Circle object
    }

    public double getArea()      /** Return the area of this circle */
    ..
    public void setRadius(double newRadius) /** Set new radius for this circle */
    ..
}  

DEMO: demo/03-classes/11-copy

How to use the copy constructor

 Before: (fails when radius is private)

    public static void main(String[] args) 
    {
        Circle circle1 = new Circle(4);
      
        // Make a copy of circle1
        Circle circle2 = new Circle();
        circle2.radius = circle1.radius;  // Fail due to private access
    } 


Using "copy" constructor: public static void main(String[] args) { Circle circle1 = new Circle(4); Circle circle2; circle2 = new Circle(circle1); // Use "copy" constructor to make Circle System.out.println( circle2.getArea() ); circle2.setRadius(10); // Proof that we made a copy System.out.println( circle1.getArea() ); // Unchanged System.out.println( circle2.getArea() ); }

DEMO: demo/03-classes/11-copy