Java/Class/Constructor
Содержание
- 1 A constructor for copying an object of the same
- 2 Constructor calls during inheritance
- 3 Constructor initialization with composition
- 4 Constructors and polymorphism don"t produce what you might expect
- 5 Constructors can have arguments
- 6 Create a new instance of a class by calling a constructor with arguments
- 7 Demonstration of a simple constructor
- 8 Order of constructor calls
- 9 Paying attention to exceptions in constructors
- 10 Show Constructors conflicting
- 11 Show that if your class has no constructors, your superclass constructors still get called
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>