练习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{
}