Java编程思想第四版第八章练习

练习1:创建一个Cycle类,它具有子类Unicycle,Bicycle和TriCycle.演示每一个类型的实例都可以经由ride()向上转型为Cycle。

public class Exercise8_1 {
    static void ride(Cycle c) {

    }
     public static void main(String[] args) {
          ride(new Unicycle());
          ride(new Bicycle());
          ride(new Tricycle());
    }
}

class Unicycle extends Cycle{

}
class Bicycle extends Cycle{

}
class Tricycle extends Cycle{

}

练习2: 在几何图形的示例中添加@Override注解。

public class Shape {
      public void draw() {}
      public void erase() {}
    }
public class Circle extends Shape {
     @Override public void draw() { System.out.println("Circle.draw()"); }
     @Override public void erase() {System.out.println("Circle.erase()"); }
    }
public class Square extends Shape {
    @Override public void draw() { System.out.println("Square.draw()"); }
    @Override public void erase() { System.out.println("Square.erase()"); }
    }
public class Triangle extends Shape {
    @Override public void draw() {System.out.println("Triangle.draw()"); }
    @Override public void erase() { System.out.println("Triangle.erase()"); }
    }
public class Shapes {
      private static RandomShapeGenerator gen =
        new RandomShapeGenerator();
      public static void main(String[] args) {
        Shape[] s = new Shape[9];
        // Fill up the array with shapes:
        for(int i = 0; i < s.length; i++)
          s[i] = gen.next();
        // Make polymorphic method calls:
        for(Shape shp : s)
          shp.draw();
      }
    }

练习3:在基类Shape().java中添加一个新方法,用于打印一条消息,但导出类中不要覆盖这个方法。请解释发生了什么。现在,在其中一个导出类中覆盖该方法,而在其他的导出类不予覆盖,观察又有什么发生。最后,在所有的导出类中覆盖这个方法。

public class Circle extends Shape {
     @Override public void draw() { System.out.println("Circle.draw()"); }
     @Override public void erase() {System.out.println("Circle.erase()"); }
              public void msg() {
                  System.out.println("Circle.msg");
              }
    }
public class Square extends Shape {
    @Override public void draw() { System.out.println("Square.draw()"); }
    @Override public void erase() { System.out.println("Square.erase()"); }
     public void msg() {
      System.out.println("Square.msg");
     }
    }
public class Triangle extends Shape {
    @Override public void draw() {System.out.println("Triangle.draw()"); }
    @Override public void erase() { System.out.println("Triangle.erase()"); }
          public void msg() {
              System.out.println("Triangle.msg");
     }
    }
public class Shape {
      public void draw() {}
      public void erase() {}
      public void msg() {
          System.out.println("Shape.msg()");
      }
    }
public class Shapes {
      private static RandomShapeGenerator gen =
        new RandomShapeGenerator();
      public static void main(String[] args) {
        Shape[] s = new Shape[9];
        // Fill up the array with shapes:
        for(int i = 0; i < s.length; i++)
          s[i] = gen.next();
        // Make polymorphic method calls:
        for(Shape shp : s) {
            shp.draw();
            shp.msg();
        }

      }

    }

练习4:向Shape.java中添加一个新的Shape类型,并在main()方法中验证:多态对新类型的作用是否与在旧类型中的一样。

public class Shapes {
      public static void main(String[] args) {
        Shape[] s = {new Square(), new Triangle(),new Terahedron(),new Circle()};
        for(Shape shp : s) {
            shp.draw();
            shp.msg();
        }

      }

    }
    public class Terahedron extends Shape{
    public void draw() {
        System.out.println("Terahedron.draw()");
    }


    public void erase() {
        System.out.println("Terahedron.erase()");
    }

        public void msg() {
            System.out.println("Terahedron.msg()");
        }
}

练习5:以练习1为基础,在Cycle中添加wheels()方法,它将返回轮子的数量。修改ride()方法,并验证多态起作用了。

public class Exercise8_5 {
    static void ride(Cycle c) {
        System.out.println("Number of wheels : "+c.wheels());
    }
     public static void main(String[] args) {
          ride(new Unicycle());
          ride(new Bicycle());
          ride(new Tricycle());
    }
}
class Cycle{
    public int wheels() {
        return 0;
    }
}
class Unicycle extends Cycle{
    public int wheels() {
        return 1;
    }
}
class Bicycle extends Cycle{
    public int wheels() {
        return 2;
    }
}
class Tricycle extends Cycle{
    public int whee`
s() {
        return 3;
    }
}

练习6:修改Music3.java,使what()方法成为根Object的toString方法.试用System.out.Printfln()方法打印Instrucment对象(不用向上转型)

class Instrument {
  void play(Note n) { System.out.println("Instrument.play() " + n); }
    public String toString() {
        return "Instrument";
    }
  void adjust() { System.out.println("Adjusting Instrument"); }
}

class Wind extends Instrument {
  void play(Note n) { System.out.println("Wind.play() " + n); }
    public String toString() {
        return "Wind";
    }
  void adjust() { System.out.println("Adjusting Wind"); }
}   

class Percussion extends Instrument {
  void play(Note n) { System.out.println("Percussion.play() " + n); }
  public String toString() {
        return "Percussion";
    }
  void adjust() { System.out.println("Adjusting Percussion"); }
}

class Stringed extends Instrument {
  void play(Note n) { System.out.println("Stringed.play() " + n); }
  public String toString() {
      return "Stringed";
    }

  void adjust() { System.out.println("Adjusting Stringed"); }
}

class Brass extends Wind {
  void play(Note n) { System.out.println("Brass.play() " + n); }
  void adjust() { System.out.println("Adjusting Brass"); }
}

class Woodwind extends Wind {
  void play(Note n) {System.out.println("Woodwind.play() " + n); }

  public String toString() {
      return "Woodwind";
    }
}   

public class Music3 {
  // Doesn't care about type, so new types
  // added to the system still work right:
  public static void tune(Instrument i) {
    // ...
    i.play(Note.MIDDLE_C);
  }
  public static void tuneAll(Instrument[] e) {
    for(Instrument i : e) {
        // tune(i);
         System.out.println(i.toString());
    }

  } 
  public static void main(String[] args) {
    // Upcasting during addition to the array:
    Instrument[] orchestra = {
      new Wind(),
      new Percussion(),
      new Stringed(),
      new Brass(),
      new Woodwind()
    };
    tuneAll(orchestra);
  }
}

练习7:想Music3.java添加一个新的类型Instrument,并验证多态性是否作用于所添加的新类型。

public class Exercise8_7 {
    public static void main(String[] args) {
          Instrument[] orchestra = {
                  new Wind(),
                  new Percussion(),
                  new Stringed(),
                  new Brass(),
                  new Woodwind(),
                  new Electronic()
                };
          for(Instrument i:orchestra) {
              i.play(Note.MIDDLE_C);
              System.out.println(i);
              i.adjust();
          }
    }
}
 class Electronic extends Instrument{
     void play(Note n) { System.out.println("Electronic.play() " + n); }
        public String toString() {
            return "Electronic";
        }
 }

练习8:修改Music3.java,使其可以像Shapes.java中的方式那样可以随机创建Instrument对象

public class Exercise8_8 {
      public static void main(String[] args) {
        InstrumentGenerator generator =new InstrumentGenerator();
        for (int i = 0; i < 20; i++) {
            System.out.println(generator.next());
        }
    }
}
class InstrumentGenerator{
    Random random = new Random(47);
    public Instrument next() {
        switch (random.nextInt(6)) {
        default:
        case 0: return new Wind();
        case 1: return new Percussion();
        case 2: return new Stringed();
        case 3: return new Brass();
        case 4: return new Woodwind();
        case 5: return new Electronic`
);

        }
    }
}

练习9:创建Rodent(啮齿动物):Mnouse(老鼠),Gerbil(鼹鼠),Hamster(大颊鼠),等等这样一个的继承层次结构。在基类中,提供对所有的Rodent都通用的方法,在导出类中,根据特定的Rodent类型覆盖这些方法,以便它们执行不同的行为。创建一个Robent数组,填充不同的Rodent类型,然后调用基类方法,观察发生什么情况。**

public class Exercise8_9 {
    public static void main(String[] args) {
         Rodent rodents[] = {new Mouse(),new Gerbil(),new Hamster()};
         for(Rodent r: rodents) {
             r.hop();
             r.scurry();
             r.reproduce();
             System.out.println(r);
         }
    }
}
class Rodent{
    public void hop() {System.out.println("Rodent hopping");}
    public void scurry() {System.out.println("Rodent scurrying");}
    public void reproduce() {System.out.println("Making more Rodent");}
    public String toString() {return "Eodent";}
}
class Mouse extends Rodent{
    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 Gerbil extends Rodent{
    public void hop() {System.out.println("Gerbil hopping");}
    public void scurry() {System.out.println("Gerbil scurrying");}
    public void reproduce() {System.out.println("Making more Gerbil");}
    public String toString() {return "Gernil";}
}
class Hamster extends Rodent{
    public void hop() {System.out.println("Hamster hopping");}
    public void scurry() {System.out.println("Hamster scurrying");}
    public void reproduce() {System.out.println("Making more Hamster");}
    public String toString() {return "Hamster";}
}

练习10: 创建一个包含两个方法的基类。在第一个方法中可以调用第二个方法。然后产生一个继承自该基类的导出类,且覆盖基类中的第二个方法。为该导出类创建一个对象,将他向上转型到基类并调用第一个方法,解释发生的情况。

public class Exercise8_10 {
   public static void main(String[] args) {
      TwoMethods twoMethods = new Inherited();
      twoMethods.m1();
}
}
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");
    }
}

练习11: 向Sandwich.java中添加 Pickle类。

class Pickle {
      Pickle() { System.out.println("Pickle()"); }
    }
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 {
              Bread b = new Bread();
              Cheese c = new Cheese();
              Lettuce l = new Lettuce();
              Pickle p = new Pickle();
      public Sandwich() { System.out.println("Sandwich()"); }
      public static void main(String[] args) `
        new Sandwich();
      }
    }

练习12:修改练习9,使其能够演示基类和导出类的初始化顺序。然后向基类和导出类中添加成员对象,并说明构造期间初始化发生的顺序。

public class Exercise8_12 {
    public static void main(String[] args) {
         new Hamster2();
    }
}
class Member{
    public Member(String id) {
        System.out.println("Member contructor"+id);
    }
}
class Rodent2{
    Member m1 = new Member("r1"),m2 = new Member("r2");
    public Rodent2() {System.out.println("Rodent Conteuctor");}
    public void hop() {System.out.println("Rodent hopping");}
    public void scurry() {System.out.println("Rodent scurrying");}
    public void reproduce() {System.out.println("Making more Rodent");}
    public String toString() {return "Eodent";}
}
class Mouse2 extends Rodent2{
    Member m1 = new Member("m1"),m2 = new Member("m2");
    public Mouse2() {System.out.println("Mouse Conteuctor");}
    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 Gerbil2 extends Rodent2{
    Member m1 = new Member("G1"),m2 = new Member("G2");
    public Gerbil2() {System.out.println("Gerbil Conteuctor");}
    public void hop() {System.out.println("Gerbil hopping");}
    public void scurry() {System.out.println("Gerbil scurrying");}
    public void reproduce() {System.out.println("Making more Gerbil");}
    public String toString() {return "Gernil";}
}
class Hamster2 extends Rodent2{
    Member m1 = new Member("h1"),m2 = new Member("h2");
    public Hamster2() {System.out.println("Hamster Conteuctor");}
    public void hop() {System.out.println("Hamster hopping");}
    public void scurry() {System.out.println("Hamster scurrying");}
    public void reproduce() {System.out.println("Making more Hamster");}
    public String toString() {return "Hamster";}
}

练习13 : 在ReferenceCounting.java中添加一个finalized()方法,用来校验终止条件


class Shared {
      private int refcount = 0;
      private static long counter = 0;
      private final long id = counter++;
      public Shared() {
          System.out.println("Creating " + this);
      }
      public void addRef() { refcount++; }
      protected void dispose() {
        if(--refcount == 0)
              System.out.println("Disposing " + this);
      }
      public String toString() { return "Shared " + id; }

    protected void finalize() {
         if(refcount!=0) {
              System.out.println("ERROR : object is not properly clean-up");
         }
    }
    }

    class Composing {
      private Shared shared;
      private static long counter = 0;
      private final long id = counter++;
      public Composing(Shared shared) {
          System.out.println("Creating " + this);
        this.shared = shared;
        this.shared.addRef();
      }
      protected void dispose() {
        System.out.println("disposing " + this);
        shared.dispose();
      }
      public String toString() { return "Composing " + id; }
    }

    public class ReferenceCounting {
      public static void main(String[] args) {
        Shared shared = new Shared();
        Composing[] composing = { new Composing(shared),
          new Composing(shared), new Composing(shared),
          new Composing(shared), new Composing(shared) };
        for(Composing c : composing)
          c.dispose();
        new Composing(new Shared());
        System.gc();
      }
    }

修改练习12,使其某个成员对象变为具有引用计数的共享对象,并证明它可以正常运行。

public class Exercise8_14 {
    public static void main(String[] args) {
        SharedMember member = new SharedMember();
        Rodent3[] rodents = {
                new Mouse3(member),
                new Gerbil3(member),
                new Hamster3(member)
                };
        for(Rodent3 r:rodents) {
            r.dispose();
        }
    }
}
class NonSharedMember{
    public NonSharedMember(String id) {
        System.out.println("NonSharedMember contructor"+id);
    }
}
class SharedMember{
    private int Recount;
    public void addRef() {
        System.out.println("Number of reference:" + ++Recount);
    }
    public void dispose() {
        if(--Recount==0) {
            System.out.println("Disposing"+this);
        }
    }
    public SharedMember(){
      System.out.println("SharedMember Constructor");   
    }
    public String toString() {
        return "SharedMemebr";
    }
}
class Rodent3{
    private SharedMember sharedMember;
    Member m1 = new Member("r1"),m2 = new Member("r2");
    public Rodent3(SharedMember sharedMember) {
        System.out.println("Rodent Conteuctor");
        this.sharedMember = sharedMember;
        this.sharedMember.addRef();
        }
    protected void dispose() {
        System.out.println("Disposing "+this);
        sharedMember.dispose();

    }
    public void hop() {System.out.println("Rodent hopping");}
    public void scurry() {System.out.println("Rodent scurrying");}
    public void reproduce() {System.out.println("Making more Rodent");}
    public String toString() {return "Eodent";}
}
class Mouse3 extends Rodent3{
    Member m1 = new Member("m1"),m2 = new Member("m2");
    public Mouse3(SharedMember sharedMember) {
        super(sharedMember);
        System.out.println("Mouse Conteuctor");

    }
    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 m1 = new Member("G1"),m2 = new Member("G2");
    public Gerbil3(SharedMember sharedMember) {
        super(sharedMember);
        System.out.println("Gerbil Conteuctor");}
    public void hop() {System.out.println("Gerbil hopping");}
    public void scurry() {System.out.println("Gerbil scurrying");}
    public void reproduce() {System.out.println("Making more Gerbil");}
    public String toString() {return "Gernil";}
}
class Hamster3 extends Rodent3{
    Member m1 = new Member("h1"),m2 = new Member("h2");
    public Hamster3(SharedMember sharedMember) {
        super(sharedMember); 
        System.out.println("Hamster Conteuctor");
        }
    public void hop() {System.out.println("Hamster hopping");}
    public void scurry() {System.out.println("Hamster scurrying");}
    public void reproduce() {System.out.println("Making more Hamster");}
    public String toString() {return "Hamster";}
}

练习15: 在PolyConstructors.java中添加一个RectangularGlyph,并证明会出现本节所描述的问题

//PolyConstructors.java
class Glyph {
      void draw() {  System.out.println("Glyph.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);
      }
    }
public class Exercise8_15 {
    public static void main(String[] args) {
        new RoundGlyph(5);
        new RectangularGlyph(2, 2);
    }
}
class RectangularGlyph extends Glyph{
    private int width = 4;
    private int height = 5;

    public RectangularGlyph(int width,int height) {
        this.width = width;
        this.height = height;
        System.out.println("RectangularGlyph.width = "+width+" height = "+height);
    }
    public void draw() {
        System.out.println("RectangularGlyph.area = "+(width*height));
    }
}

练习16: 遵循Transmogrify.java这个例子,创建一个Starship类,包含一个AlertStatus引用,此引用可以指示三种不同的状态。纳入一些可以改变这些状态的方法

public class Exercise8_16 {
     public static void main(String[] args) {
        Starship starship = new Starship();
        System.out.println(starship);
        starship.change(new YellowAlertStatus());
        System.out.println(starship);
        starship.change(new RedAlertStatus());
        System.out.println(starship);

    }
}
class AlertStatus{
    public String getStatus() {
        return "None";
    }
}
class RedAlertStatus extends AlertStatus{
    public String getStatus() {
        return "Red";
    }
}
class YellowAlertStatus extends AlertStatus{
    public String getStatus() {
        return "Yellow";
    }
}
class GreenAlertStatus extends AlertStatus{
    public String getStatus() {
        return "Green";
    }
}
class Starship{
    private AlertStatus alertStatus = new GreenAlertStatus();
    public void change(AlertStatus iStatus) {
        alertStatus = iStatus;
    }
    public String toString() {
        return alertStatus.getStatus();
    }
}

练习17:使用练习1中的Cycle的层次结构哦,在Unicycle 和Bicycle中添加balance方法,而Tricycle中国不添加。创建这三种类型的实例,并将他们向上转型为Cycle数组。在该数组的每一个元素上都尝试调用balance,并观察结果。然后将他们向下转型,再次调用balance(),并观察将所发生什么。

public class Exercise8_17 {
   public static void main(String[] args) {
       Cycle3 []cycle = {new Unicycle3(),new Bicycle3(),new Tricycle3()};
//     cycle[0].balance();
//     cycle[1].balance();
//     cycle[2].balance();
       ((Unicycle3) cycle[0]).balance();
       ((Bicycle3) cycle[1]).balance();
     //  ((Tricycle3) cycle[2]).balance();
}
}
class Cycle3{

}
class Unicycle3 extends Cycle3{
    public void balance() {};
}
class Bicycle3 extends Cycle3{
    public void balance() {};
}
class Tricycle3 extends Cycle3{

}

猜你喜欢

转载自blog.csdn.net/lelouch_j_zs/article/details/78504213
今日推荐