2015-09-07 11:44:36 -06:00
|
|
|
// references/CopyConstructor.java
|
2015-12-15 11:47:04 -08:00
|
|
|
// (c)2016 MindView LLC: see Copyright.txt
|
2015-11-15 15:51:35 -08:00
|
|
|
// We make no guarantees that this code is fit for any purpose.
|
|
|
|
// Visit http://mindviewinc.com/Books/OnJava/ for more book information.
|
2015-06-15 17:47:35 -07:00
|
|
|
// A constructor to copy an object of the same
|
2016-01-25 18:05:55 -08:00
|
|
|
// type, as an attempt to create a local copy
|
2015-06-15 17:47:35 -07:00
|
|
|
import java.lang.reflect.*;
|
|
|
|
|
|
|
|
class FruitQualities {
|
|
|
|
private int weight;
|
|
|
|
private int color;
|
|
|
|
private int firmness;
|
|
|
|
private int ripeness;
|
|
|
|
private int smell;
|
|
|
|
// etc.
|
2015-11-03 12:00:44 -08:00
|
|
|
// No-arg constructor:
|
2015-06-15 17:47:35 -07:00
|
|
|
public FruitQualities() {
|
|
|
|
// Do something meaningful...
|
|
|
|
}
|
|
|
|
// Other constructors:
|
|
|
|
// ...
|
|
|
|
// Copy constructor:
|
|
|
|
public FruitQualities(FruitQualities f) {
|
|
|
|
weight = f.weight;
|
|
|
|
color = f.color;
|
|
|
|
firmness = f.firmness;
|
|
|
|
ripeness = f.ripeness;
|
|
|
|
smell = f.smell;
|
|
|
|
// etc.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Seed {
|
|
|
|
// Members...
|
2015-11-03 12:00:44 -08:00
|
|
|
public Seed() { /* No-arg constructor */ }
|
2015-06-15 17:47:35 -07:00
|
|
|
public Seed(Seed s) { /* Copy constructor */ }
|
|
|
|
}
|
|
|
|
|
|
|
|
class Fruit {
|
|
|
|
private FruitQualities fq;
|
|
|
|
private int seeds;
|
|
|
|
private Seed[] s;
|
2016-01-25 18:05:55 -08:00
|
|
|
public Fruit(FruitQualities q, int seedCount) {
|
2015-06-15 17:47:35 -07:00
|
|
|
fq = q;
|
|
|
|
seeds = seedCount;
|
|
|
|
s = new Seed[seeds];
|
|
|
|
for(int i = 0; i < seeds; i++)
|
|
|
|
s[i] = new Seed();
|
|
|
|
}
|
|
|
|
// Other constructors:
|
|
|
|
// ...
|
|
|
|
// Copy constructor:
|
|
|
|
public Fruit(Fruit f) {
|
|
|
|
fq = new FruitQualities(f.fq);
|
|
|
|
seeds = f.seeds;
|
|
|
|
s = new Seed[seeds];
|
|
|
|
// Call all Seed copy-constructors:
|
|
|
|
for(int i = 0; i < seeds; i++)
|
|
|
|
s[i] = new Seed(f.s[i]);
|
|
|
|
// Other copy-construction activities...
|
|
|
|
}
|
2016-01-25 18:05:55 -08:00
|
|
|
// This allows derived constructors (or other
|
2015-06-15 17:47:35 -07:00
|
|
|
// methods) to put in different qualities:
|
2016-01-25 18:05:55 -08:00
|
|
|
protected void addQualities(FruitQualities q) {
|
2015-06-15 17:47:35 -07:00
|
|
|
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 to base copy-constructor
|
|
|
|
// Other copy-construction activities...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ZebraQualities extends FruitQualities {
|
|
|
|
private int stripedness;
|
2015-11-03 12:00:44 -08:00
|
|
|
// No-arg constructor:
|
2015-06-15 17:47:35 -07:00
|
|
|
public ZebraQualities() {
|
|
|
|
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 ripen(Tomato t) {
|
|
|
|
// Use the "copy constructor":
|
2016-01-25 18:05:55 -08:00
|
|
|
t = new Tomato(t); // (1)
|
2015-06-15 17:47:35 -07:00
|
|
|
System.out.println("In ripen, t is a " +
|
|
|
|
t.getClass().getName());
|
|
|
|
}
|
|
|
|
public static void slice(Fruit f) {
|
2016-01-25 18:05:55 -08:00
|
|
|
f = new Fruit(f); // Hmmm... will this work? (2)
|
2015-06-15 17:47:35 -07:00
|
|
|
System.out.println("In slice, f is a " +
|
|
|
|
f.getClass().getName());
|
|
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public static void ripen2(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(NoSuchMethodException |
|
|
|
|
SecurityException |
|
|
|
|
InstantiationException |
|
|
|
|
IllegalAccessException |
|
|
|
|
IllegalArgumentException |
|
|
|
|
InvocationTargetException e) {
|
|
|
|
System.out.println(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public static void slice2(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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
|
|
Tomato tomato = new Tomato();
|
|
|
|
ripen(tomato); // OK
|
|
|
|
slice(tomato); // OOPS!
|
|
|
|
ripen2(tomato); // OK
|
|
|
|
slice2(tomato); // OK
|
|
|
|
GreenZebra g = new GreenZebra();
|
|
|
|
ripen(g); // OOPS!
|
|
|
|
slice(g); // OOPS!
|
|
|
|
ripen2(g); // OK
|
|
|
|
slice2(g); // OK
|
|
|
|
g.evaluate();
|
|
|
|
}
|
2015-09-07 11:44:36 -06:00
|
|
|
}
|
|
|
|
/* Output:
|
2015-06-15 17:47:35 -07:00
|
|
|
In ripen, t is a Tomato
|
|
|
|
In slice, f is a Fruit
|
|
|
|
In ripen2, t is a Tomato
|
|
|
|
In slice2, f is a Tomato
|
|
|
|
In ripen, t is a Tomato
|
|
|
|
In slice, f is a Fruit
|
|
|
|
In ripen2, t is a GreenZebra
|
|
|
|
In slice2, f is a GreenZebra
|
2015-09-07 11:44:36 -06:00
|
|
|
*/
|