Java/Class/Constructor

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

A constructor for copying an object of the same

   <source lang="java">

// : 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();
 }

} ///:~


 </source>
   
  
 
  



Constructor calls during inheritance

   <source lang="java">

// : 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();
 }

} ///:~


 </source>
   
  
 
  



Constructor initialization with composition

   <source lang="java">

// : 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);
 }

} ///:~


 </source>
   
  
 
  



Constructors and polymorphism don"t produce what you might expect

   <source lang="java">

// : 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);
 }

} ///:~


 </source>
   
  
 
  



Constructors can have arguments

   <source lang="java">

// : 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);
 }

} ///:~


 </source>
   
  
 
  



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

   <source lang="java">
  

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);
 }

}


 </source>
   
  
 
  



Demonstration of a simple constructor

   <source lang="java">

// : 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();
 }

} ///:~


 </source>
   
  
 
  



Order of constructor calls

   <source lang="java">

// : 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();
 }

} ///:~


 </source>
   
  
 
  



Paying attention to exceptions in constructors

   <source lang="java">

// : 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();
   }
 }

} ///:~


 </source>
   
  
 
  



Show Constructors conflicting

   <source lang="java">

/*

* 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
 }

}


 </source>
   
  
 
  



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

   <source lang="java">

/*

* 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>");
 }

}


 </source>