Think in java 答案_Chapter 6(-)

阅前声明: http://blog.csdn.net/heimaoxiaozi/archive/2007/01/19/1487884.aspx

Exercise 1

/****************** Exercise 1 ******************

 * Create two classes, A and B, with default

 * constructors (empty argument lists) that

 * announce themselves. Inherit a new class

 * called C from A, and create a member of class

 * B inside C. Do not create a constructor for C.

 * Create an object of class C and observe the

 * results.

 ***********************************************/

class A {

  public A() {

    System.out.println("A()");

  }

}

 

class B {

  public B() {

    System.out.println("B()");

  }

}

 

class C extends A {

  B b = new B();

}

 

public class E01_SimpleInheritance {

  public static void main(String args[]) {

    new C();

  }

}

//+M java E01_SimpleInheritance

 

**The output is:

A()

B()

 

**Which shows that the base-class constructor is called first, then the member object constructors.

Exercise 2

/****************** Exercise 2 ******************

 * Modify Exercise 1 so that A and B have

 * constructors with arguments instead of default

 * constructors. Write a constructor for C and

 * perform all initialization within C's

 * constructor.

 ***********************************************/

class A2 {

  public A2(String s) {

    System.out.println("A2(): " + s);

  }

}

 

class B2 {

  public B2(String s) {

    System.out.println("2B(): " + s);

  }

}

 

class C2 extends A2 {

  B2 b;

  public C2(String s) {

    super(s);

    b = new B2(s);

  }

}

 

public class E02_SimpleInheritance2 {

  public static void main(String args[]) {

    new C2("Init string");

  }

}

//+M java E02_SimpleInheritance2

 **(The ‘2’s were added to keep

the class names from clashing, as they are in the same directory).

Remember that super calls the base-class constructor and must

    be the first call in a derived-class constructor. The output is:

A2(): Init string

B2(): Init string

Exercise 3

/****************** Exercise 3 ******************

 * Create a simple class. Inside a second class,

 * define a field for an object of the first

 * class. Use lazy initialization to instantiate

 * this object.

 ***********************************************/

class Simple {

  String s;

  public Simple(String si) {

    s = si;

  }

  public String toString() {

    return s;

  }

  public void setString(String sNew) {

    s = sNew;

  }

}

 

class Second {

  Simple simple;

  String s;

  public Second(String si) {

    s = si; // 'simple' not initialized

  }

  public void check() {

    if(simple == null)

      System.out.println("not initialized");

    else

      System.out.println("initialized");

  }

  private Simple lazy() {

    if(simple == null) {

      System.out.println("Creating Simple");

      simple = new Simple(s);

    }

    return simple;

  }

  public Simple getSimple() { return lazy(); }

  public String toString() {

    return lazy().toString();

  }

  public void setSimple(String sNew) {

    lazy().setString(sNew);

  }

}

 

public class E03_Composition {

  public static void main(String args[]) {

    Second second = new Second("Init String");

    second.check();

    System.out.println(second.getSimple());

    second.check();

    System.out.println(second); // toString() call

    second.setSimple("New String");

  }

}

//+M java E03_Composition

 

**The Simple class has some data and methods. The Second class performs the lazy initialization through the lazy( ) method, which is called by all the other methods in order to access the Simple object. The lazy( ) method creates the object if it hasn’t already been created, and then returns it.

I’ve added some print statements to show when the initialization happens, and that it

doesn’t happen more than once. The program output is:

not initialized

Creating Simple

Init String

initialized

Init String

Exercise 4

/****************** Exercise 4 ******************

 * Inherit a new class from class Detergent.

 * Override scrub() and add a new method called

 * sterilize().

 ***********************************************/

public class E04_NewDetergent extends Detergent {

  public void scrub() {

    append("Overriden Scrub");

    super.scrub(); // Doesn't have to be first

  }

  public void sterilize() {

    append("Sterilize");

  }

  public static void main(String args[]) {

    E04_NewDetergent nd =

      new E04_NewDetergent();

    nd.dilute();

    nd.scrub();

    nd.sterilize();

    nd.print();

  }

}

//+M java E04_NewDetergent

 

**So the program will compile, here is the Detergent class from the book:

// Reproduced from Thinking in Java, 2nd edition

// so that E04_NewDetergent.java will build.

 

class Cleanser {

  private String s = new String("Cleanser");

  public void append(String a) { s += a; }

  public void dilute() { append(" dilute()"); }

  public void apply() { append(" apply()"); }

  public void scrub() { append(" scrub()"); }

  public void print() { System.out.println(s); }

  public static void main(String[] args) {

    Cleanser x = new Cleanser();

    x.dilute(); x.apply(); x.scrub();

    x.print();

  }

}

 

public class Detergent extends Cleanser {

  // Change a method:

  public void scrub() {

    append(" Detergent.scrub()");

    super.scrub(); // Call base-class version

  }

  // Add methods to the interface:

  public void foam() { append(" foam()"); }

  // Test the new class:

  public static void main(String[] args) {

    Detergent x = new Detergent();

    x.dilute();

    x.apply();

    x.scrub();

    x.foam();

    x.print();

    System.out.println("Testing base class:");

    Cleanser.main(args);

  }

}

 

Exercise 5

/****************** Exercise 5 ******************

 * Take the file Cartoon.java and comment out the

 * constructor for the Cartoon class. Explain

 * what happens.

 ***********************************************/

class Art {

  Art() {

    System.out.println("Art constructor");

  }

}

 

class Drawing extends Art {

  Drawing() {

    System.out.println("Drawing constructor");

  }

}

 

class Cartoon extends Drawing {

//!  Cartoon() {

//!    System.out.println("Cartoon constructor");

//!  }

}

 

public class E05_Cartoon2 {

  public static void main(String args[]) {

    new Cartoon();

  }

}

//+M java E05_Cartoon2

**

With the constructor written out, the output is:

Art constructor

Drawing constructor

Cartoon constructor

**If the constructor is commented out, the output is:

Art constructor

Drawing constructor

 

**The compiler synthesizes the default Cartoon constructor, and in this generated constructor it automatically calls the base-class Drawing default constructor, which in turn automatically calls the base-class Art default constructor.

**The compiler will ensure that some constructor is called, and if you don’t explicitly call a constructor it will call the default constructor for you, if one is available. The default constructor is not available for a class if one or more constructors are explicitly defined, but not the default.

Exercise 6

/****************** Exercise 6 ******************

 * Take the file Chess.java and comment out the

 * constructor for the Chess class. Explain what

 * happens.

 ***********************************************/

class Game {

  Game(int i) {

    System.out.println("Game constructor");

  }

}

 

class BoardGame extends Game {

  BoardGame(int i) {

    super(i);

    System.out.println("BoardGame constructor");

  }

}

 

class Chess extends BoardGame {

//!  Chess() {

//!    super(11);

//!    System.out.println("Chess constructor");

//!  }

}

 

public class E06_Chess2 {

  public static void main(String args[]) {

    new Chess();

  }

}

//=M @echo Compile by hand to see results

**

**The program won’t compile, because the compiler cannot synthesize a default constructor for Chess, because BoardGame does not have a default constructor that can be used in Chess’ default constructor. Since BoardGame has a defined constructor that takes an argument, the compiler cannot assume that you’ve simply forgotten to create any constructors and generate one for you.

Because this compilation fails, the //=M directive takes it out of the build process.

Exercise 7

/****************** Exercise 7 ******************

 * Prove that default constructors are created

 * for you by the compiler.

 ***********************************************/

public class E07_AutoDefault {

  public static void main(String args[]) {

    new E07_AutoDefault();

  }

}

//+M java E07_AutoDefault

**

The mere fact that this compiles is the proof – a constructor is called, and none was defined.

Exercise 8

/****************** Exercise 8 ******************

 * Prove that the base-class constructors are (a)

 * always called, and (b) called before

 * derived-class constructors.

 ***********************************************/

class Base1 {

  public Base1() {

    System.out.println("Base1");

  }

}

 

class Derived1 extends Base1 {

  public Derived1() {

    System.out.println("Derived1");

  }

}

 

class Derived2 extends Derived1 {

  public Derived2() {

    System.out.println("Derived2");

  }

}

 

public class E08_ConstructorOrder {

  public static void main(String args[]) {

    new Derived2();

  }

}

//+M java E08_ConstructorOrder

Base1

Derived1

Derived2

Exercise 9

/****************** Exercise 9 ******************

 * Create a base class with only a nondefault

 * constructor, and a derived class with both a

 * default and nondefault constructor. In the

 * derived-class constructors, call the

 * base-class constructor.

 ***********************************************/

class BaseNonDefault {

  public BaseNonDefault(int i) {}

}

 

class DerivedTwoConstructors

extends BaseNonDefault {

  public DerivedTwoConstructors() {

    super(47);

  }

  public DerivedTwoConstructors(int i) {

    super(i);

  }

}

 

public class E09_CallBaseConstructor {

  public static void main(String args[]) {

    new DerivedTwoConstructors();

    new DerivedTwoConstructors(74);

  }

}

 

//+M java E09_CallBaseConstructor

 

 

 

Exercise 10

 

/****************** Exercise 10 *****************

 * Create a class called Root that contains an

 * instance of each of classes (that you also

 * create) named Component1, Component2, and

 * Component3. Derive a class Stem from Root that

 * also contains an instance of each "component."

 * All classes should have default constructors

 * that print a message about that class.

 ***********************************************/

class Component1 {

  public Component1() {

    System.out.println("Component1");

  }

}

class Component2 {

  public Component2() {

    System.out.println("Component2");

  }

}

 

class Component3 {

  public Component3() {

    System.out.println("Component3");

  }

}

 

class Root {

  Component1 c1 = new Component1();

  Component2 c2 = new Component2();

  Component3 c3 = new Component3();

  public Root() {

    System.out.println("Root");

  }

}

 

class Stem extends Root {

  Component1 c1 = new Component1();

  Component2 c2 = new Component2();

  Component3 c3 = new Component3();

  public Stem() {

    System.out.println("Stem");

  }

}

 

public class E10_ConstructorOrder {

  public static void main(String args[]) {

    new Stem();

  }

}

 

//+M java E10_ConstructorOrder

 

**The output is:

 

Component1

 

Component2

 

Component3

 

Root

 

Component1

 

Component2

 

Component3

 

Stem

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值