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