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: 

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
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.

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

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
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button