class

Copy Constructor example

This is an example of how to create a copy constructor in a class. We have set the example, in order to demonstrate the copy constructor and its use between classes and their subclasses following the steps below:

  • We have created FruitQualities class, Seed class and Fruit class, that all have copy constructor. 
  • We have also created Tomato class, that extends Fruit, ZebraQualities class that extends FruitQualities, and GreenZebra class that extends Tomato. All subclasses call their super classes’ copy constructors in their copy constructors.
  • We create a new instance of Tomato, that is tomato.
  • We call ripenFunc(Tomato t), using the tomato, where we use its copy constructor to create another new instance. We get the name of the class of the object created, using getClass() and getName() API methods of Class. The object created belongs to Tomato class.
  • We call sliceFunc(Fruit f), using the tomato. This method creates a new Fruit instance, using the copy constructor. The object created belongs to Fruit class.
  • We call ripenFunc2(Tomato t), using the tomato, where we get the Constructor of the object, using its class name, with getClass() API method and using its constructor, with getConstructor() API method of Class. Then we use the newInstance(Object... initargs) API method of Constructor to get a new instance of the object. The object belongs to Tomato class.
  • We call sliceFunc2(Fruit f), using the tomato, that does the same steps as ripenFunc2(Tomato t) does, with a Fruit f as parameter. The object created belongs to Tomato class.
  • We follow the same steps, creating an instance of GreenZebra, that extends the Tomato class. The results from the two first methods are, first a Tomato object, then a Fruit object, whereas in the last two methods a GreenZebra object is created.

Let’s take a look at the code snippet that follows: 

package com.javacodegeeks.snippets.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class FruitQualities {

    private int w;
    private int c;
    private int firmval;
    private int ripen;
    private int sml;

    // etc.
    public FruitQualities() { // Default constructor

  // Do something meaningful...
    }

    // Other constructors:
    // ...
    // Copy constructor:
    public FruitQualities(FruitQualities frq) {

  w = frq.w;

  c = frq.c;

  firmval = frq.firmval;

  ripen = frq.ripen;

  sml = frq.sml;

  // etc.
    }
}

class Seed {
    // Members...

    public Seed() { /*

   * Default constructor

   */

    }

    public Seed(Seed s) { /*

   * Copy constructor

   */

    }
}

class Fruit {

    private FruitQualities fq;
    private int seedamnt;
    private Seed[] s;

    public Fruit(FruitQualities q, int seedCount) {

  fq = q;

  seedamnt = seedCount;

  s = new Seed[seedamnt];

  for (int i = 0; i < seedamnt; i++) {


s[i] = new Seed();

  }
    }

    // Other constructors:
    // ...
    // Copy constructor:
    public Fruit(Fruit f) {

  fq = new FruitQualities(f.fq);

  seedamnt = f.seedamnt;

  s = new Seed[seedamnt];

  // Call all Seed copy-constructors:

  for (int i = 0; i < seedamnt; i++) {


s[i] = new Seed(f.s[i]);

  }

  // Other copy-construction activities...
    }

    // To allow derived constructors (or other
    // methods) to put in different qualities:
    protected void addQualities(FruitQualities q) {

  fq = q;
    }

    protected FruitQualities getQualities() {

  return fq;
    }
}

class Tomato extends Fruit {

    public Tomato() {

  super(new FruitQualities(), 100);
    }

    public Tomato(Tomato t) { // Copy-constructor

  super(t); // Upcast for base copy-constructor

  // Other copy-construction activities...
    }
}

class ZebraQualities extends FruitQualities {

    private int stripedness;

    public ZebraQualities() { // Default constructor

  super();

  // do something meaningful...
    }

    public ZebraQualities(ZebraQualities z) {

  super(z);

  stripedness = z.stripedness;
    }
}

class GreenZebra extends Tomato {

    public GreenZebra() {

  addQualities(new ZebraQualities());
    }

    public GreenZebra(GreenZebra g) {

  super(g); // Calls Tomato(Tomato)

  // Restore the right qualities:

  addQualities(new ZebraQualities());
    }

    public void evaluate() {

  ZebraQualities zq = (ZebraQualities) getQualities();

  // Do something with the qualities

  // ...
    }
}

public class CopyConstructor {

    public static void main(String[] args) {

  Tomato tomato = new Tomato();

  ripenFunc(tomato); // OK

  sliceFunc(tomato); // OOPS!

  ripenFunc2(tomato); // OK

  sliceFunc2(tomato); // OK

  GreenZebra g = new GreenZebra();

  ripenFunc(g); // OOPS!

  sliceFunc(g); // OOPS!

  ripenFunc2(g); // OK

  sliceFunc2(g); // OK

  g.evaluate();

    }

    public static void ripenFunc(Tomato t) {

  // Use the "copy constructor":

  t = new Tomato(t);

  System.out.println("In ripen, t is a " + t.getClass().getName());
    }

    public static void sliceFunc(Fruit f) {

  f = new Fruit(f); // Hmmm... will this work?

  System.out.println("In slice, f is a " + f.getClass().getName());
    }

    public static void ripenFunc2(Tomato t) {

  try {


Class c = t.getClass();


// Use the "copy constructor":


Constructor ct = c.getConstructor(new Class[]{c});


Object obj = ct.newInstance(new Object[]{t});


System.out.println("In ripen2, t is a " + obj.getClass().getName());

  } catch (Exception e) {


System.out.println(e);

  }
    }

    public static void sliceFunc2(Fruit f) {

  try {


Class c = f.getClass();


Constructor ct = c.getConstructor(new Class[]{c});


Object obj = ct.newInstance(new Object[]{f});


System.out.println("In slice2, f is a " + obj.getClass().getName());

  } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {


System.out.println(e);

  }
    }
}

Output:

In ripenFunc, t is a methodoverloading.Tomato
In sliceFunc, f is a methodoverloading.Fruit
In ripenFunc2, t is a methodoverloading.Tomato
In sliceFunc2, f is a methodoverloading.Tomato
In ripenFunc, t is a methodoverloading.Tomato
In sliceFunc, f is a methodoverloading.Fruit
In ripenFunc2, t is a methodoverloading.GreenZebra
In sliceFunc2, f is a methodoverloading.GreenZebra

 
This was an example of how to create and use copy constructors in Java.

Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is an applications developer in a wide variety of applications/services. He is currently acting as the team leader and technical architect for a proprietary service creation and integration platform for both the IT and Telecom industries in addition to a in-house big data real-time analytics solution. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button