Think in java 答案_Chapter 6(二)

来源:互联网 发布:阿里云服务器到期 编辑:程序博客网 时间:2024/03/28 19:16

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

Exercise 11
/****************** Exercise 11 *****************
 * Modify Exercise 10 so that each class only has
 * nondefault constructors.
 ***********************************************/
class Component1b {
 public Component1b(int i) {
    System.out.println("Component1b");
 }
}
class Component2b {
 public Component2b(int i) {
    System.out.println("Component2b");
 }
}
 
class Component3b {
 public Component3b(int i) {
    System.out.println("Component3b");
 }
}
 
class Rootb {
 Component1b c1 = new Component1b(1);
 Component2b c2 = new Component2b(2);
 Component3b c3 = new Component3b(3);
 public Rootb(int i) {
    System.out.println("Rootb");
 }
}
 
class Stemb extends Rootb {
 Component1b c1 = new Component1b(4);
 Component2b c2 = new Component2b(5);
 Component3b c3 = new Component3b(6);
 public Stemb(int i) {
    super(i);
    System.out.println("Stemb");
 }
}
 
public class E11_ConstructorOrder2 {
 public static void main(String args[]) {
    new Stemb(47);
 }
}
//+M java E11_ConstructorOrder2
Exercise 12
 
/****************** Exercise 12 *****************
 * Add a proper hierarchy of cleanup() methods to
 * all the classes in Exercise 11.
 ***********************************************/
 
class Component1c {
 public Component1c(int i) {
    System.out.println("Component1c");
 }
 publicvoid cleanup() {
    System.out.println("Component1c cleanup");
 }
}
class Component2c {
 public Component2c(int i) {
    System.out.println("Component2c");
 }
 publicvoid cleanup() {
    System.out.println("Component2c cleanup");
 }
}
 
class Component3c {
 public Component3c(int i) {
    System.out.println("Component3c");
 }
 publicvoid cleanup() {
    System.out.println("Component3c cleanup");
 }
}
 
class Rootc {
 Component1c c1 = new Component1c(1);
 Component2c c2 = new Component2c(2);
 Component3c c3 = new Component3c(3);
 public Rootc(int i) {
    System.out.println("Rootc");
 }
 publicvoid cleanup() {
    System.out.println("Rootc cleanup");
    c3.cleanup();
    c2.cleanup();
    c1.cleanup();
 }
}
 
class Stemc extends Rootc {
 Component1c c1 = new Component1c(4);
 Component2c c2 = new Component2c(5);
 Component3c c3 = new Component3c(6);
 public Stemc(int i) {
    super(i);
    System.out.println("Stemc");
 }
 publicvoid cleanup() {
    System.out.println("Stemc cleanup");
    c3.cleanup();
    c2.cleanup();
    c1.cleanup();
    super.cleanup();
 }
}
 
publicclass E12_Cleanup {
 publicstaticvoid main(String args[]) {
    new Stemc(47).cleanup();
 }
}
//+M java E12_Cleanup
**It’s important to call the cleanup( ) methods in
 the reverse order of initialization. You can see this in the output:
Component1c
Component2c
Component3c
Rootc
Component1c
Component2c
Component3c
Stemc
Stemc cleanup
Component3c cleanup
Component2c cleanup
Component1c cleanup
Rootc cleanup
Component3c cleanup
Component2c cleanup
Component1c cleanup
Exercise 13
 
/****************** Exercise 13 *****************
 * Create a class with a method that is
 * overloaded three times. Inherit a new class,
 * add a new overloading of the method, and show
 * that all four methods are available in the
 * derived class.
 ***********************************************/
 
class ThreeOverloads {
 publicvoid f(int i) {
    System.out.println("f(int i)");
 }
 publicvoid f(char c) {
    System.out.println("f(char c)");
 }
 publicvoid f(double d) {
    System.out.println("f(double d)");
 }
}
 
class MoreOverloads extends ThreeOverloads {
 publicvoid f(String s) {
    System.out.println("f(String s)");
 }
}
 
publicclass E13_InheritedOverloading {
 publicstaticvoid main(String args[]) {
    MoreOverloads mo = new MoreOverloads();
    mo.f(1);
    mo.f('c');
    mo.f(1.1);
    mo.f("Hello");
 }
}
 
//+M java E13_InheritedOverloading
 
 
Exercise 14
 
/****************** Exercise 14 *****************
 * In Car.java add a service() method to Engine
 * and call this method in main().
 ***********************************************/
 
class Engine {
 publicvoid start() {}
 publicvoid rev() {}
 publicvoid stop() {}
 publicvoid service() {}
}
 
class Wheel {
 publicvoid inflate(int psi) {}
}
 
class Window {
 publicvoid rollup() {}
 publicvoid rolldown() {}
}
 
class Door {
 public Window window = new Window();
 publicvoid open() {}
 publicvoid close() {}
}
 
class Car {
 public Engine engine = new Engine();
 public Wheel[] wheel = new Wheel[4];
 public Door left = new Door(),
       right = new Door(); // 2-door
 public Car() {
    for(int i = 0; i < 4; i++)
      wheel[i] = new Wheel();
 }
}
 
publicclass E14_EngineService {
 publicstaticvoid main(String[] args) {
    Car car = new Car();
    car.left.window.rollup();
    car.wheel[0].inflate(72);
    car.engine.service();
 }
}
//+M java E14_EngineService
Exercise 15
 
/****************** Exercise 15 *****************
 * Create a class inside a package. Your class
 * should contain a protected method. Outside of
 * the package, try to call the protected method
 * and explain the results. Now inherit from your
 * class and call the protected method from
 * inside a method of your derived class.
 ***********************************************/
 
import c06.protect.*;
 
class Derived extends ClassWithProtected {
 publicvoid g() {
    f(); // Accessible in derived class
 }
}
 
publicclass E15_Protected {
 publicstaticvoid main(String args[]) {
    //! ClassWithProtected().f(); // Cannot access
    new Derived().g();
 }
}
 
 
package c06.protect;
publicclass ClassWithProtected {
 protectedvoid f() {
    System.out.println("Protected Method");
 }
}
 
//+M java E15_Protected
 
Exercise 16
 
/****************** Exercise 16 *****************
 * Create a class called Amphibian. From this,
 * inherit a class called Frog. Put appropriate
 * methods in the base class. In main(), create a
 * Frog and upcast it to Amphibian, and
 * demonstrate that all the methods still work.
 ***********************************************/
class Amphibian {
 publicvoid moveInWater() {
    System.out.println("Moving in Water");
 }
 publicvoid moveOnLand() {
    System.out.println("Moving on Land");
 }
}
 
class Frog extends Amphibian {}
 
publicclass E16_Frog {
 publicstaticvoid main(String args[]) {
    Amphibian a = new Frog();
    a.moveInWater();
    a.moveOnLand();
 }
}
 
//+M java E16_Frog
**The output is:
Moving in Water
Moving on Land
 
 
Exercise 17
 
/****************** Exercise 17 *****************
 * Modify Exercise 16 so that Frog overrides the
 * method definitions from the base class
 * (provides new definitions using the same
 * method signatures). Note what happens in
 * main().
 ***********************************************/
 
class Amphibian2 {
 publicvoid moveInWater() {
    System.out.println("Moving in Water");
 }
 publicvoid moveOnLand() {
    System.out.println("Moving on Land");
 }
}
 
class Frog2 extends Amphibian2 {
 publicvoid moveInWater() {
    System.out.println("Frog swimming");
 }
 publicvoid moveOnLand() {
    System.out.println("Frog jumping");
 }
}
 
publicclass E17_Frog2 {
 publicstaticvoid main(String args[]) {
    Amphibian2 a = new Frog2();
    a.moveInWater();
    a.moveOnLand();
 }
}
//+M java E17_Frog2
**Now the output is
Frog swimming
Frog jumping
**Even though the compiler has a reference to an amphibian, 
which might make you think that it would call the amphibian 
methods, the frog methods actually get called. Since a is actually 
a reference to a frog, this is the behavior you want. That’s 
polymorphism – the right behavior happens even if you are 
talking to a base-class reference.
Exercise 18
 
/****************** Exercise 18 *****************
 * Create a class with a static final field and a
 * final field and demonstrate the difference
 * between the two.
 ***********************************************/
 
class SelfCounter {
 privatestaticint count = 0;
 privateint id = count++;
 public String toString() {
    return"SelfCounter " + id;
 }
}
 
class WithFinalFields {
 final SelfCounter scf = new SelfCounter();
 staticfinal SelfCounter scsf =
    new SelfCounter();
 public String toString() {
    return"scf = " + scf + "/nscsf = " + scsf;
 }
}
 
publicclass E18_FinalFields {
 publicstaticvoid main(String args[]) {
    System.out.println("First object:");
    System.out.println(new WithFinalFields());
    System.out.println("Second object:");
    System.out.println(new WithFinalFields());
 }
}
//+M java E18_FinalFields
**The output is:
First object:
scf = SelfCounter 1
scsf = SelfCounter 0
Second object:
scf = SelfCounter 2
scsf = SelfCounter 0
**Note that the static final field was initialized first, because it got the value of zero as the WithFinalFields class was being loaded. And in bothe instances of WithFinalFields, the static final field has the same value because it is only initialized upon class loading, whereas the regular final field gets a different value for each instance.
Exercise 19
/****************** Exercise 19 *****************
 * Create a class with a blank final reference to
 * an object. Perform the initialization of the
 * blank final inside all constructors. (Note: in
 * the 2nd edition of the book, this read "inside
 * a method (not the constructor) right before
 * you use it" which was incorrect).
 * Demonstrate the guarantee that the final must
 * be initialized before use, and that it cannot
 * be changed once initialized.
 
 ***********************************************/
class WithBlankFinal {
 private final Integer i;
 // Without this constructor, I got a compile-
 // time error about initialization:
 public WithBlankFinal(int ii) {
    i = new Integer(ii);
 }
 public Integer geti() {
    // This wouldn't compile:
    //!if(i == null)
    //! i = new Integer(47);
    return i;
 }
}
 
public class E19_BlankFinal {
 public static void main(String args[]) {
    WithBlankFinal wbf = new WithBlankFinal(10);
    System.out.println(wbf.geti());
 }
} 
//+M java E19_BlankFinal
**The exercise described in the 2nd edition of the book implied that you could initialize the blank final outside of the constructor, which is not correct. It’s hard to know whether I just got confused, or if the JDK version I was using allowed me to do this. The above solution shows the correction.
Exercise 20
/****************** Exercise 20 *****************
 * Create a class with a final method. Inherit
 * from that class and attempt to override that
 * method.
 ***********************************************/
class WithFinal {
 final void f() {}
}
 
public class E20_FinalMethod extends WithFinal {
 // Compiler error -- cannot override final method:
 //! void f() {}
 public static void main(String args[]) {
    new E20_FinalMethod();
 }
}
//+M java E20_FinalMethod
Exercise 21
/****************** Exercise 21 *****************
 * Create a final class and attempt to inherit
 * from it.
 ***********************************************/
final class FinalClass {}
 
public class E21_FinalClass
 // Compiler error -- cannot inherit from
 // final class:
 //! extends FinalClass
 {
 public static void main(String args[]) {
    
  }
}
//+M java E21_FinalClass
Exercise 22
/****************** Exercise 22 *****************
 * Prove that class loading takes place only
 * once. Prove that loading may be caused by
 * either the creation of the first instance of
 * that class, or the access of a static member.
 ***********************************************/
class LoadTest {
 // The static clause is executed
 // upon class loading:
 static {
    System.out.println("Loading LoadTest");
 }
 static void staticMember() {}
}
 
public class E22_ClassLoading {
 public static void main(String args[]) {
    System.out.println("Calling static member");
    LoadTest.staticMember();
    System.out.println("Creating an object");
    new LoadTest();
 }
}
//+M java E22_ClassLoading
**When you run this program, you get the output:
Calling static member
Loading LoadTest
Creating an object
**Now try modifying the code to put the object creation before the static member call, and you’ll see that the object creation will cause the object to be loaded. Actually, a constructor is a static method even though you don’t explicitly use the static keyword when defining it.
Exercise 23
/****************** Exercise 23 *****************
 * In Beetle.java, inherit a specific type of
 * beetle from class Beetle, following the same
 * format as the existing classes. Trace and
 * explain the output.
 ***********************************************/
class Insect {
 int i = 9;
 int j;
 Insect() {
    prt("i = " + i + ", j = " + j);
    j = 39;
 }
 static int x1 =
    prt("static Insect.x1 initialized");
 static int prt(String s) {
    System.out.println(s);
    return 47;
 }
}
 
class Beetle extends Insect {
 int k = prt("Beetle.k initialized");
 Beetle() {
    prt("k = " + k);
    prt("j = " + j);
 }
 static int x2 =
    prt("static Beetle.x2 initialized");
}
 
 
class JapaneseBeetle extends Beetle {
 int m = prt("JapaneseBeetle.m initialized");
 JapaneseBeetle() {
    System.out.println("m = " + m);
    System.out.println("j = " + j);
 }
 static int x3 = prt(
    "static JapaneseBeetle.x3 initialized");
}
 
public class E23_JapaneseBeetle {
 public static void main(String args[]) {
    new JapaneseBeetle();
 }
}
//+M java E23_JapaneseBeetle
**The output is:
static Insect.x1 initialized
static Beetle.x2 initialized
static JapaneseBeetle.x3 initialized
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39
JapaneseBeetle.m initialized
m = 47
j = 39
**The static variables are initialized when the class is loaded; notice that the base class of the entire hierarchy is loaded first, then the next-derived class, finally the most-derived class. Then the object is created, and the non-static members are initialized, also starting at the root class.
 
原创粉丝点击