Java/Class/Constructor

Материал из Java эксперт
Перейти к: навигация, поиск

A constructor for copying an object of the same

 
// : appendixa:CopyConstructor.java
// A constructor for copying an object of the same
// type, as an attempt to create a local copy.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
import java.lang.reflect.Constructor;
class FruitQualities {
  private int weight;
  private int color;
  private int firmness;
  private int ripeness;
  private int smell;
  // etc.
  public FruitQualities() { // Default constructor
    // 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...
  public Seed() { /* Default constructor */
  }
  public Seed(Seed s) { /* Copy constructor */
  }
}
class Fruit {
  private FruitQualities fq;
  private int seeds;
  private Seed[] s;
  public Fruit(FruitQualities q, int seedCount) {
    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...
  }
  // 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 ripen(Tomato t) {
    // Use the "copy constructor":
    t = new Tomato(t);
    System.out.println("In ripen, t is a " + t.getClass().getName());
  }
  public static void slice(Fruit f) {
    f = new Fruit(f); // Hmmm... will this work?
    System.out.println("In slice, f is a " + f.getClass().getName());
  }
  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 (Exception e) {
      System.out.println(e);
    }
  }
  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 (Exception 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();
  }
} ///:~





Constructor calls during inheritance

 
// : c06:Cartoon.java
// Constructor calls during inheritance.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
class Art {
  Art() {
    System.out.println("Art constructor");
  }
}
class Drawing extends Art {
  Drawing() {
    System.out.println("Drawing constructor");
  }
}
public class Cartoon extends Drawing {
  public Cartoon() {
    System.out.println("Cartoon constructor");
  }
  public static void main(String[] args) {
    Cartoon x = new Cartoon();
  }
} ///:~





Constructor initialization with composition

 
// : c06:Bath.java
// Constructor initialization with composition.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
class Soap {
  private String s;
  Soap() {
    System.out.println("Soap()");
    s = new String("Constructed");
  }
  public String toString() {
    return s;
  }
}
public class Bath {
  private String // Initializing at point of definition:
      s1 = new String("Happy"), s2 = "Happy", s3, s4;
  private Soap castille;
  private int i;
  private float toy;
  public Bath() {
    System.out.println("Inside Bath()");
    s3 = new String("Joy");
    i = 47;
    toy = 3.14f;
    castille = new Soap();
  }
  public String toString() {
    if (s4 == null) // Delayed initialization:
      s4 = new String("Joy");
    return "s1 = " + s1 + "\n" + "s2 = " + s2 + "\n" + "s3 = " + s3 + "\n"
        + "s4 = " + s4 + "\n" + "i = " + i + "\n" + "toy = " + toy
        + "\n" + "castille = " + castille;
  }
  public static void main(String[] args) {
    Bath b = new Bath();
    System.out.println(b);
  }
} ///:~





Constructors and polymorphism don"t produce what you might expect

 
// : c07:PolyConstructors.java
// Constructors and polymorphism don"t produce what you might expect.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
abstract class Glyph {
  abstract void draw();
  Glyph() {
    System.out.println("Glyph() before draw()");
    draw();
    System.out.println("Glyph() after draw()");
  }
}
class RoundGlyph extends Glyph {
  private int radius = 1;
  RoundGlyph(int r) {
    radius = r;
    System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
  }
  void draw() {
    System.out.println("RoundGlyph.draw(), radius = " + radius);
  }
}
public class PolyConstructors {
  public static void main(String[] args) {
    new RoundGlyph(5);
  }
} ///:~





Constructors can have arguments

 
// : c04:SimpleConstructor2.java
// Constructors can have arguments.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
class Rock2 {
  Rock2(int i) {
    System.out.println("Creating Rock number " + i);
  }
}
public class SimpleConstructor2 {
  public static void main(String[] args) {
    for (int i = 0; i < 10; i++)
      new Rock2(i);
  }
} ///:~





Create a new instance of a class by calling a constructor with arguments

   
import java.lang.reflect.Constructor;
/**
 * Handy reflection routines.
 */
public abstract class Reflect {
  /**
   * Create a new instance of a class by calling a constructor with arguments.
   */
  public static Object newInstance(String className, Class[] signature, Object[] args)
      throws Exception {
    Class cls = Class.forName(className);
    Constructor constructor = cls.getConstructor(signature);
    return constructor.newInstance(args);
  }
}





Demonstration of a simple constructor

 
// : c04:SimpleConstructor.java
// Demonstration of a simple constructor.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
class Rock {
  Rock() { // This is the constructor
    System.out.println("Creating Rock");
  }
}
public class SimpleConstructor {
  public static void main(String[] args) {
    for (int i = 0; i < 10; i++)
      new Rock();
  }
} ///:~





Order of constructor calls

 
// : c07:Sandwich.java
// Order of constructor calls.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
class Meal {
  Meal() {
    System.out.println("Meal()");
  }
}
class Bread {
  Bread() {
    System.out.println("Bread()");
  }
}
class Cheese {
  Cheese() {
    System.out.println("Cheese()");
  }
}
class Lettuce {
  Lettuce() {
    System.out.println("Lettuce()");
  }
}
class Lunch extends Meal {
  Lunch() {
    System.out.println("Lunch()");
  }
}
class PortableLunch extends Lunch {
  PortableLunch() {
    System.out.println("PortableLunch()");
  }
}
public class Sandwich extends PortableLunch {
  private Bread b = new Bread();
  private Cheese c = new Cheese();
  private Lettuce l = new Lettuce();
  public Sandwich() {
    System.out.println("Sandwich()");
  }
  public static void main(String[] args) {
    new Sandwich();
  }
} ///:~





Paying attention to exceptions in constructors

 
// : c09:Cleanup.java
// Paying attention to exceptions in constructors.
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
class InputFile {
  private BufferedReader in;
  public InputFile(String fname) throws Exception {
    try {
      in = new BufferedReader(new FileReader(fname));
      // Other code that might throw exceptions
    } catch (FileNotFoundException e) {
      System.err.println("Could not open " + fname);
      // Wasn"t open, so don"t close it
      throw e;
    } catch (Exception e) {
      // All other exceptions must close it
      try {
        in.close();
      } catch (IOException e2) {
        System.err.println("in.close() unsuccessful");
      }
      throw e; // Rethrow
    } finally {
      // Don"t close it here!!!
    }
  }
  public String getLine() {
    String s;
    try {
      s = in.readLine();
    } catch (IOException e) {
      throw new RuntimeException("readLine() failed");
    }
    return s;
  }
  public void dispose() {
    try {
      in.close();
      System.out.println("dispose() successful");
    } catch (IOException e2) {
      throw new RuntimeException("in.close() failed");
    }
  }
}
public class Cleanup {
  public static void main(String[] args) {
    try {
      InputFile in = new InputFile("Cleanup.java");
      String s;
      int i = 1;
      while ((s = in.getLine()) != null)
        ; // Perform line-by-line processing here...
      in.dispose();
    } catch (Exception e) {
      System.err.println("Caught Exception in main");
      e.printStackTrace();
    }
  }
} ///:~





Show Constructors conflicting

 
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */

/** Show Constructors conflicting */
public class Constructors {
  /** Constructor */
  public Constructors() {
    System.out.println("In the constructor");
  }
  /** Constructor that throws */
  public Constructors(int value) {
    if (value < 0)
      throw new IllegalArgumentException("Constructors: value < 0");
  }
  /** Not a Constructor, because of void */
  public void Constructors() {  // EXPECT COMPILE ERROR some compilers
    System.out.println("In void Constructor()");
  }
  void method1() {
    for (int i=0; i<5; i++)
      System.out.println(i);
  }
  public static void main(String[] a) {
    Constructors l = new Constructors();
    l.method1();
    l.Constructors();
    new Constructors(-1);    // expect Exception
  }
}





Show that if your class has no constructors, your superclass constructors still get called

 
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */

/** Show that if your class has no constructors, your superclass"
 * constructors still get called.
 */
public class InheritConstructor extends SomeOtherClass {
  public static void main(String[] c) {
    new InheritConstructor().run();
  }
  public void run() {
    System.out.println("In InheritConstructor::run");
  }
}
// This is the class that we extend.
class SomeOtherClass {
  SomeOtherClass() {
    System.out.println("In SomeOtherClass::<init>");
  }
}