Think in java 答案

    技术2022-05-11  41

      阅前声明: http://blog.csdn.net/heimaoxiaozi/archive/2007/01/19/1487884.aspx Exercise 8 /****************** Exercise 8 *****************  * Create a class as abstract without including  * any abstract methods, and verify that you  * cannot create any instances of that class.  ***********************************************/ abstract class NoAbstractMethods {  void f() { System.out.println("f()"); } }   public class E08_Abstract {  public static void main(String args[]) {     // Compile-time error: class is abstract,     // cannot be instantiated.     //! new NoAbstractMethods();  } } //+M java E08_Abstract   Exercise 9 /****************** Exercise 9 *****************  * Add class Pickle to Sandwich.java.  ***********************************************/ 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 Pickle {  Pickle() { System.out.println("Pickle()"); } }   class Lunch extends Meal {  Lunch() { System.out.println("Lunch()");} }   class PortableLunch extends Lunch {  PortableLunch() {     System.out.println("PortableLunch()");  } }   class Sandwich extends PortableLunch {  Bread b = new Bread();  Cheese c = new Cheese();  Lettuce l = new Lettuce();  Pickle p = new Pickle();  Sandwich() {     System.out.println("Sandwich()");  } }   public class E09_Pickle {  public static void main(String args[]) {     new Sandwich();  } } //+M java E09_Pickle   **The output is: Meal() Lunch() PortableLunch() Bread() Cheese() Lettuce() Pickle() Sandwich() ** Note that the Pickle object is created in order, after the other member objects. Exercise 10 /****************** Exercise 10 *****************  * Modify Exercise 6 so that it demonstrates the  * order of initialization of the base classes  * and derived classes. Now add member objects to  * both the base and derived classes, and show  * the order in which their initialization occurs  * during construction.  ***********************************************/ class Member {  private static int counter = 0;  private int id = ++counter;  public Member() {     System.out.println(       "Member constructor " + id);  } }   class Rodent3 {  Member m = new Member();  public Rodent3() {     System.out.println("Rodent constructor");  }  public void hop() {     System.out.println("Rodent hopping");  }  public void scurry() {     System.out.println("Rodent scurrying");  }  public void reproduce() {     System.out.println("Making more Rodents");  }  public String toString() {     return "Rodent";  } }   class Mouse3 extends Rodent3 {  Member m = new Member();  public Mouse3() {     System.out.println("Mouse constructor");  }  public void hop() {     System.out.println("Mouse hopping");  }  public void scurry() {     System.out.println("Mouse scurrying");  }  public void reproduce() {     System.out.println("Making more Mice");  }  public String toString() {     return "Mouse";  } }   class Gerbil3 extends Rodent3 {  Member m = new Member();  public Gerbil3() {     System.out.println("Gerbil constructor");  }  public void hop() {     System.out.println("Gerbil hopping");  }  public void scurry() {     System.out.println("Gerbil scurrying");  }  public void reproduce() {     System.out.println("Making more Gerbils");  }  public String toString() {     return "Gerbil";  } }   class Hamster3 extends Rodent3 {  Member m = new Member();  public Hamster3() {     System.out.println("Hamster constructor");  }  public void hop() {     System.out.println("Hamster hopping");  }  public void scurry() {     System.out.println("Hamster scurrying");  }  public void reproduce() {     System.out.println("Making more Hamsters");  }  public String toString() {     return "Hamster";  } }     public class E10_RodentInitialization {  public static void main(String args[]) {     new Hamster3();  } }    //+M java E10_RodentInitialization **The output for creating the Hamster3 object is: Member constructor 1 Member constructor 2 Rodent constructor Member constructor 7 Member constructor 8 Hamster constructor ** The base class is initialized first, starting with the member objects in their order of definition, then the derived class starting with its member objects. Exercise 11 /****************** Exercise 11 *****************  * Create a 3-level inheritance hierarchy. Each  * class in the hierarchy should have a  * finalize() method, and it should properly call  * the base-class version of finalize().  * Demonstrate that your hierarchy works  * properly.  ***********************************************/ class Base {  public Base() {     System.out.println("Base()");  }  protected void finalize() {     System.out.println("Base.finalize()");  } }   class Derived1 extends Base {  public Derived1() {     System.out.println("Derived1()");  }  protected void finalize() {     System.out.println("Derived1.finalize()");     super.finalize();  } }   class Derived2 extends Derived1 {  public Derived2() {     System.out.println("Derived2()");  }  protected void finalize() {     System.out.println("Derived2.finalize()");     super.finalize();  } }    public class E11_ProperFinalization {  public static void main(String args[]) {     new Derived2();     System.gc();  } }    //+M java E11_ProperFinalization **The output is: Base() Derived1() Derived2() Derived2.finalize() Derived1.finalize() Base.finalize() ** That the most-derived class must be finalized first, then the class it’s derived from, etc.; that is, that the order of finalization be in the reverse order of construction. This is important because the code in the most-derived class may depend on the existence of any of the elements of the base classes. Exercise 12 /****************** Exercise 12 *****************  * Create a base class with two methods. In the  * first method, call the second method. Inherit  * a class and override the second method. Create  * an object of the derived class, upcast it to  * the base type, and call the first method.  * Explain what happens.  ***********************************************/ class TwoMethods {  public void m1() {     System.out.println("Inside m1, calling m2");     m2();  }  public void m2() {     System.out.println("Inside m2");  } }   class Inherited extends TwoMethods {  public void m2() {     System.out.println("Inside Inherited.m2");  } }   public class E12_MethodCalls {  public static void main(String args[]) {     TwoMethods x = new Inherited();     x.m1();  } }    //+M java E12_MethodCalls **The output is: Inside m1, calling m2 Inside Inherited.m2 ** The first method isn’t overriden, but it calls the second method, which is. Java will always use the most-derived method it can find for the object type. If you’re not thinking about this, it can be surprising. However, it can also be very powerful – this is the way the Template Method design pattern works (see Thinking in Patterns, downloadable from www.BruceEckel.com). Exercise 13 /****************** Exercise 13 *****************  * Create a base class with an abstract print()  * method that is overridden in a derived class.  * The overridden version of the method prints  * the value of an int variable defined in the  * derived class. At the point of definition of  * this variable, give it a nonzero value. In the  * base-class constructor, call this method. In  * main(), create an object of the derived type,  * and then call its print() method. Explain the  * results.  ***********************************************/ class BaseWithPrint {  public BaseWithPrint() {     print();  }  public void print() {     System.out.println("BaseWithPrint.print");  } }   class DerivedWithPrint extends BaseWithPrint {  int i = 47;  public void print() {     System.out.println("i = " + i);  } }   public class E13_Initialization {  public static void main(String args[]) {     DerivedWithPrint dp = new DerivedWithPrint();     dp.print();  } }    //+M java E13_Initialization **The output is: i = 0 i = 47 **When the base-class constructor is called, the derived-class initialization has not yet been run, so the value of i is the default which comes from wiping the bits of the object to zero right after the storage has been allocated. **This exercise is intended to point out the dangers of calling methods inside of constructors. Although it is certainly justified at times, you should be careful because these methods may depend on some derived initialization that hasn’t yet taken place. The safest approach is to do as little as possible to set the object into a known good state, and then do any other operations separately from the constructor. Exercise 14 /****************** Exercise 14 *****************  * Following the example in Transmogrify.java,  * create a Starship class containing an  * AlertStatus reference that can indicate three  * different states. Include methods to change  * the states.  ***********************************************/ class AlertStatus {  private String status;  // Can only use the objects given in  // this class; cannot create others:  private AlertStatus(String istatus) {     status = istatus;  }  public String getStatus() {     return status;  }  public static final AlertStatus     RED = new AlertStatus("Red"),     YELLOW = new AlertStatus("Yellow"),     GREEN = new AlertStatus("Green"); }   class Starship {  private AlertStatus status = AlertStatus.GREEN;  public void setStatus(AlertStatus istatus) {     status = istatus;  }  public String toString() {     return status.getStatus();  } }   public class E14_Starship {  public static void main(String args[]) {     Starship eprise = new Starship();     System.out.println(eprise);     eprise.setStatus(AlertStatus.YELLOW);     System.out.println(eprise);     eprise.setStatus(AlertStatus.RED);     System.out.println(eprise);  } }    //+M java E14_Starship **Since there are only three different variations of the AlertStatus object needed and they are all effectively constant, I used the “enumeration” idiom to create a fixed number of objects, making the constructor private to prevent the creation of any more. **The Starship class holds a reference to an AlertStatus object, and the setStatus( ) method allows you to change this reference, effectively changing the behavior of the Starship. **The output is: Green Yellow Red **The reason this is an example of the State pattern is that the object behaves differently (when the toString( ) method is implicitly called, in the example above) depending on what state it is in. Exercise 15 /****************** Exercise 15 *****************  * Create an abstract class with no methods.  * Derive a class and add a method. Create a  * static method that takes a reference to the  * base class, downcasts it to the derived class,  * and calls the method. In main(), demonstrate  * that it works. Now put the abstract  * declaration for the method in the base class,  * thus eliminating the need for the downcast.  ***********************************************/ abstract class NoMethods {}   class Extended1 extends NoMethods {  public void f() {     System.out.println("Extended1.f");  } }   abstract class WithMethods {  abstract public void f(); }   class Extended2 extends WithMethods {  public void f() {     System.out.println("Extended2.f");  } }   public class E15_AbstractBase {  public static void test1(NoMethods nm) {     // Must downcast to access f():     ((Extended1)nm).f();  }  public static void test2(WithMethods wm) {     // No downcast necessary:     wm.f();  }  public static void main(String args[]) {     NoMethods nm = new Extended1();     test1(nm);     WithMethods wm = new Extended2();     test2(wm);  } } //+M java E15_AbstractBase **Both versions are shown here, and in test1( ) you can see how a downcast is necessary in order to call f( ) (take out the downcast if you don’t believe it). In test2( ), no downcast is necessary because the method f( ) is defined in the base class. **The output is: Extended1.f Extended2.f  

    最新回复(0)