Background information:    how to make a (true) copy of an object

  • Review::   steps 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 will only work if we can access the member variable(s)...

What is the problem ?

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

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;
    }
}  

DEMO: demo/10-classes/11-copy-constructor/Demo.java + Circle.java --- start with public radius

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/10-classes/11-copy-constructor ---- change to private and re-compile

Making copy of an object with a "copy" constructor

The "copy" constructor is a constructor that copies all the instance variables from its input parameter (= c):

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 in order to
    }                               // copy the Circle c ?               

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

The "copy" constructor is defined inside class Circle so it can access the private variables !

Making copy of an object with a "copy" constructor

To make a copy, we copy all the instance variables from Circle c to the new Circle object (this):

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 the new Circle object (this)

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

 

How to use a copy constructor   (overloaded 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 = 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/10-classes/11-copy-constructor/Demo2.java + Circle.java