Source of CopyConstructor.java


  1: //: appendixa:CopyConstructor.java
  2: // From 'Thinking in Java, 2nd ed.' by Bruce Eckel
  3: // www.BruceEckel.com. See copyright notice in CopyRight.txt.
  4: // A constructor for copying an object of the same
  5: // type, as an attempt to create a local copy.

  7: class FruitQualities {
  8:   private int weight;
  9:   private int color;
 10:   private int firmness;
 11:   private int ripeness;
 12:   private int smell;
 13:   // etc.
 14:   FruitQualities() { // Default constructor
 15:     // do something meaningful...
 16:   }
 17:   // Other constructors:
 18:   // ...
 19:   // Copy constructor:
 20:   FruitQualities(FruitQualities f) {
 21:     weight = f.weight;
 22:     color = f.color;
 23:     firmness = f.firmness;
 24:     ripeness = f.ripeness;
 25:     smell = f.smell;
 26:     // etc.
 27:   }
 28: }

 30: class Seed {
 31:   // Members...
 32:   Seed() { /* Default constructor */ }
 33:   Seed(Seed s) { /* Copy constructor */ }
 34: }

 36: class Fruit {
 37:   private FruitQualities fq;
 38:   private int seeds;
 39:   private Seed[] s;
 40:   Fruit(FruitQualities q, int seedCount) { 
 41:     fq = q;
 42:     seeds = seedCount;
 43:     s = new Seed[seeds];
 44:     for(int i = 0; i < seeds; i++)
 45:       s[i] = new Seed();
 46:   }
 47:   // Other constructors:
 48:   // ...
 49:   // Copy constructor:
 50:   Fruit(Fruit f) {
 51:     fq = new FruitQualities(f.fq);
 52:     seeds = f.seeds;
 53:     // Call all Seed copy-constructors:
 54:     for(int i = 0; i < seeds; i++)
 55:       s[i] = new Seed(f.s[i]);
 56:     // Other copy-construction activities...
 57:   }
 58:   // To allow derived constructors (or other 
 59:   // methods) to put in different qualities:
 60:   protected void addQualities(FruitQualities q) {
 61:     fq = q;
 62:   }
 63:   protected FruitQualities getQualities() {
 64:     return fq;
 65:   }
 66: }

 68: class Tomato extends Fruit {
 69:   Tomato() {
 70:     super(new FruitQualities(), 100);
 71:   }
 72:   Tomato(Tomato t) { // Copy-constructor
 73:     super(t); // Upcast for base copy-constructor
 74:     // Other copy-construction activities...
 75:   }
 76: }

 78: class ZebraQualities extends FruitQualities {
 79:   private int stripedness;
 80:   ZebraQualities() { // Default constructor
 81:     // do something meaningful...
 82:   }
 83:   ZebraQualities(ZebraQualities z) {
 84:     super(z);
 85:     stripedness = z.stripedness;
 86:   }
 87: }

 89: class GreenZebra extends Tomato {
 90:   GreenZebra() {
 91:     addQualities(new ZebraQualities());
 92:   }
 93:   GreenZebra(GreenZebra g) {
 94:     super(g); // Calls Tomato(Tomato)
 95:     // Restore the right qualities:
 96:     addQualities(new ZebraQualities());
 97:   }
 98:   void evaluate() {
 99:     ZebraQualities zq = 
100:       (ZebraQualities)getQualities();
101:     // Do something with the qualities
102:     // ...
103:   }
104: }

106: public class CopyConstructor {
107:   public static void ripen(Tomato t) {
108:     // Use the "copy constructor":
109:     t = new Tomato(t); 
110:     System.out.println("In ripen, t is a " +
111:       t.getClass().getName());
112:   }
113:   public static void slice(Fruit f) {
114:     f = new Fruit(f); // Hmmm... will this work?
115:     System.out.println("In slice, f is a " +
116:       f.getClass().getName());
117:   }
118:   public static void main(String[] args) {
119:     Tomato tomato = new Tomato();
120:     ripen(tomato); // OK
121:     slice(tomato); // OOPS!
122:     GreenZebra g = new GreenZebra();
123:     ripen(g); // OOPS!
124:     slice(g); // OOPS!
125:     g.evaluate();
126:   }
127: } ///:~