Thinking in Java 第四版完整版 第八章練習題 多型
阿新 • • 發佈:2019-01-09
Thinking in Java 第四版完整版 第八章練習題,記錄一下(jdk1.8.0)
1.
/**
* 練習1:建立一個Cycle類,它具有子類Unicycle、Bicycle和
* Tricycle。演示每一個型別的示例都可以經由ride()方法向上
* 轉型為Cycle。
* @author admin11
* @date 2018年3月28日
*/
class Cycle {}
class Unicycle extends Cycle {}
class Bicycle extends Cycle {}
class Tricycle extends Cycle {}
public class Exercise801 {
public static void ride(Cycle cycle) {}
public static void main(String[] args) {
ride(new Unicycle());
ride(new Bicycle());
ride(new Tricycle());
}
}
2.
/**
* 練習2:在幾何圖形的示例中新增@Override註解。
* @author admin11
* @date 2018年3月28日
*/
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()");
}
}
import java.util.Random;
public class RandomShapeGenerator {
private Random rand = new Random(47);
public Shape next() {
switch (rand.nextInt(3)) {
default:
case 0:
return new Circle();
case 1:
return new Square();
case 2:
return new Triangle();
}
}
}
public class Shapes {
private static RandomShapeGenerator gen = new RandomShapeGenerator();
public static void main(String[] args) {
Shape[] s = new Shape[9];
for (int i = 0; i < s.length; i++) {
s[i] = gen.next();
}
for (Shape shape : s) {
shape.draw();
}
}
}
3.
/**
* 練習3:在基類Shapes.java中新增一個新方法,用於列印一條訊息,
* 但匯出類中不要覆蓋這個方法。請解釋發生了什麼。現在,在其中一個匯出
* 類中覆蓋該方法,而在其他的匯出類中不予覆蓋,觀察又有什麼發生。最後,
* 在所有的匯出類中覆蓋這個方法。
* @author admin11
* @date 2018年3月28日
*/
public class Shape {
public void draw() {}
public void erase() {}
public void testPrint() {
System.out.println("shape.testPrint()");
}
}
public class Circle extends Shape {
@Override
public void draw() {
System.out.println("Circle.draw()");
}
@Override
public void erase() {
System.out.println("Circle.erase()");
}
@Override
public void testPrint() {
System.out.println("Circle.testPrint()");
}
}
public class Square extends Shape{
@Override
public void draw() {
System.out.println("Square.draw()");
}
@Override
public void erase() {
System.out.println("Square.erase()");
}
@Override
public void testPrint() {
System.out.println("Square.testPrint()");
}
}
public class Triangle extends Shape{
@Override
public void draw() {
System.out.println("Triangle.draw()");
}
@Override
public void erase() {
System.out.println("Triangle.erase()");
}
@Override
public void testPrint() {
System.out.println("Triangle.testPrint()");
}
}
import java.util.Random;
public class RandomShapeGenerator {
private Random rand = new Random(47);
public Shape next() {
switch (rand.nextInt(3)) {
default:
case 0:
return new Circle();
case 1:
return new Square();
case 2:
return new Triangle();
}
}
}
public class Shapes {
private static RandomShapeGenerator gen = new RandomShapeGenerator();
public static void main(String[] args) {
Shape[] s = new Shape[9];
for (int i = 0; i < s.length; i++) {
s[i] = gen.next();
}
for (Shape shape : s) {
shape.draw();
shape.testPrint();
}
}
}
4.
/**
* 練習4:向Shapes.java中新增一個新的Shape型別,並在main()
* 方法中驗證:多型對新型別的作用是否與在舊型別中的一樣。
* @author admin11
* @date 2018年3月28日
*/
class Shape {
public void draw() {}
public void erase() {}
public void testPrint() {
System.out.println("shape.testPrint()");
}
}
class Circle extends Shape {
@Override
public void draw() {
System.out.println("Circle.draw()");
}
@Override
public void erase() {
System.out.println("Circle.erase()");
}
@Override
public void testPrint() {
System.out.println("Circle.testPrint()");
}
}
class Square extends Shape{
@Override
public void draw() {
System.out.println("Square.draw()");
}
@Override
public void erase() {
System.out.println("Square.erase()");
}
@Override
public void testPrint() {
System.out.println("Square.testPrint()");
}
}
class Triangle extends Shape{
@Override
public void draw() {
System.out.println("Triangle.draw()");
}
@Override
public void erase() {
System.out.println("Triangle.erase()");
}
@Override
public void testPrint() {
System.out.println("Triangle.testPrint()");
}
}
class newShape extends Shape{
@Override
public void draw() {
System.out.println("newShape.draw()");
}
@Override
public void erase() {
System.out.println("newShape.erase()");
}
@Override
public void testPrint() {
System.out.println("newShape.testPrint()");
}
}
public class Exercise804 {
public static void main(String[] args) {
Shape[] sp = {new Circle(), new Square(),
new Triangle(), new newShape()};
for (Shape shape : sp) {
shape.draw();
shape.erase();
shape.testPrint();
}
}
}
5.
/**
* 練習5:以練習1為基礎,在Cycle中新增wheels()方法,它將返回
* 輪子的數量。修改ride()方法,讓它呼叫wheels()方法,並驗證
* 多型起作用了。
* @author admin11
* @date 2018年3月28日
*/
class Cycle {
public String wheels() {
return "Cycle wheels : none";
}
}
class Unicycle extends Cycle {
@Override
public String wheels() {
return "Unicycle wheels : 4";
}
}
class Bicycle extends Cycle {
@Override
public String wheels() {
return "Bicycle wheels : 2";
}
}
class Tricycle extends Cycle {
@Override
public String wheels() {
return "Tricycle wheels : 3";
}
}
public class Exercise805 {
public static void ride(Cycle cycle) {
System.out.println(cycle.wheels());
}
public static void main(String[] args) {
Cycle[] c = {new Unicycle(), new Bicycle(),
new Tricycle()};
for (Cycle cycle : c) {
ride(cycle);
}
}
}
6.
/**
* 練習6:修改Music3.java,使what()方法成為根Object的
* toString()方法。試用System.out.println()方法列印
* Instrument物件(不用向上轉型)。
* @author admin11
* @date 2018年3月28日
*/
enum Note {
MIDDLE_C, C_SHARP, B_FLAT;
}
class Instrument {
void play(Note n) {
System.out.println("Instrument.play() " + n);
}
@Override
public String toString() {
return "Instrument";
}
void adjust() {
System.out.println("Adjusting Instrument");
}
}
class Wind extends Instrument {
@Override
void play(Note n) {
System.out.println("Wind.play() " + n);
}
@Override
public String toString() {
return "Wind";
}
@Override
void adjust() {
System.out.println("Adjusting Wind");
}
}
class Percussion extends Instrument {
@Override
void play(Note n) {
System.out.println("Percussion.play() " + n);
}
@Override
public String toString() {
return "Percussion";
}
@Override
void adjust() {
System.out.println("Adjusting Percussion");
}
}
class Stringed extends Instrument {
@Override
void play(Note n) {
System.out.println("Stringed.play() " + n);
}
@Override
public String toString() {
return "Stringed";
}
@Override
void adjust() {
System.out.println("Adjusting Stringed");
}
}
class Brass extends Wind {
@Override
void play(Note n) {
System.out.println("Brass.play() " + n);
}
@Override
void adjust() {
System.out.println("Adjusting Brass");
}
}
class Woodwind extends Wind {
@Override
void play(Note n) {
System.out.println("Woodwind.play() " + n);
}
@Override
public String toString() {
return "Woodwind";
}
}
public class Exercise806 {
static Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind()
};
public static void printAll(Instrument[] e) {
for (Instrument instrument : e) {
System.out.println(instrument);
}
}
public static void main(String[] args) {
printAll(orchestra);
}
}
7.
/**
* 練習7:向Music3.java新增一個新的型別Instrument,
* 並驗證多型性是否作用於所新增的新型別。
* @author admin11
* @date 2018年3月28日
*/
enum Note {
MIDDLE_C, C_SHARP, B_FLAT;
}
class Instrument {
void play(Note n) {
System.out.println("Instrument.play() " + n);
}
@Override
public String toString() {
return "Instrument";
}
void adjust() {
System.out.println("Adjusting Instrument");
}
}
class Wind extends Instrument {
@Override
void play(Note n) {
System.out.println("Wind.play() " + n);
}
@Override
public String toString() {
return "Wind";
}
@Override
void adjust() {
System.out.println("Adjusting Wind");
}
}
class Percussion extends Instrument {
@Override
void play(Note n) {
System.out.println("Percussion.play() " + n);
}
@Override
public String toString() {
return "Percussion";
}
@Override
void adjust() {
System.out.println("Adjusting Percussion");
}
}
class Stringed extends Instrument {
@Override
void play(Note n) {
System.out.println("Stringed.play() " + n);
}
@Override
public String toString() {
return "Stringed";
}
@Override
void adjust() {
System.out.println("Adjusting Stringed");
}
}
class Brass extends Wind {
@Override
void play(Note n) {
System.out.println("Brass.play() " + n);
}
@Override
void adjust() {
System.out.println("Adjusting Brass");
}
}
class Woodwind extends Wind {
@Override
void play(Note n) {
System.out.println("Woodwind.play() " + n);
}
@Override
public String toString() {
return "Woodwind";
}
}
class Electronic extends Instrument {
@Override
void play(Note n) {
System.out.println("Electronic.play() " + n);
}
@Override
public String toString() {
return "Electronic";
}
@Override
void adjust() {
System.out.println("Adjusting Electronic");
}
}
public class Exercise807 {
public static void main(String[] args) {
Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind(),
new Electronic()
};
for (Instrument instrument : orchestra) {
instrument.play(Note.MIDDLE_C);
instrument.adjust();
System.out.println(instrument);
}
}
}
8.
import java.util.Random;
/**
* 練習8:修改Music3.java,使其可以像Shapes.java中的方式
* 那樣隨機建立Instrument物件。
* @author admin11
* @date 2018年3月28日
*/
enum Note {
MIDDLE_C, C_SHARP, B_FLAT;
}
class Instrument {
void play(Note n) {
System.out.println("Instrument.play() " + n);
}
@Override
public String toString() {
return "Instrument";
}
void adjust() {
System.out.println("Adjusting Instrument");
}
}
class Wind extends Instrument {
@Override
void play(Note n) {
System.out.println("Wind.play() " + n);
}
@Override
public String toString() {
return "Wind";
}
@Override
void adjust() {
System.out.println("Adjusting Wind");
}
}
class Percussion extends Instrument {
@Override
void play(Note n) {
System.out.println("Percussion.play() " + n);
}
@Override
public String toString() {
return "Percussion";
}
@Override
void adjust() {
System.out.println("Adjusting Percussion");
}
}
class Stringed extends Instrument {
@Override
void play(Note n) {
System.out.println("Stringed.play() " + n);
}
@Override
public String toString() {
return "Stringed";
}
@Override
void adjust() {
System.out.println("Adjusting Stringed");
}
}
class Brass extends Wind {
@Override
void play(Note n) {
System.out.println("Brass.play() " + n);
}
@Override
void adjust() {
System.out.println("Adjusting Brass");
}
}
class Woodwind extends Wind {
@Override
void play(Note n) {
System.out.println("Woodwind.play() " + n);
}
@Override
public String toString() {
return "Woodwind";
}
}
class Electronic extends Instrument {
@Override
void play(Note n) {
System.out.println("Electronic.play() " + n);
}
@Override
public String toString() {
return "Electronic";
}
@Override
void adjust() {
System.out.println("Adjusting Electronic");
}
}
class InstrumentGenerator {
public Instrument next() {
switch (new 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();
}
}
}
public class Exercise808 {
public static void main(String[] args) {
InstrumentGenerator gen = new InstrumentGenerator();
for (int i = 0; i < 10; i++) {
System.out.println(gen.next());
}
}
}
9.
/**
* 練習9:建立Rodent(齧齒動物):Mouse(老鼠),Gerbil(鼴鼠),
* Hamster(大頰鼠),等等這樣一個的繼承層次結構。在基類中,提供對所
* 有的Rodent都通用的方法,在匯出類中,根據特定的Rodent型別覆蓋
* 這些方法,以便它們執行不同的行為。建立一個Rodent陣列,填充不同
* 的Rodent型別,然後呼叫基類方法,觀察發生什麼情況。
* @author admin11
* @date 2018年3月28日
*/
class Rodent {
public void eat() {
System.out.println("eat...");
}
public void sleep() {
System.out.println("sleep...");
}
}
class Mouse extends Rodent{
@Override
public void eat() {
System.out.println("Mouse eat...");
}
@Override
public void sleep() {
System.out.println("Mouse sleep...");
}
}
class Gerbil extends Rodent {
@Override
public void eat() {
System.out.println("Gerbil eat...");
}
@Override
public void sleep() {
System.out.println("Gerbil sleep...");
}
}
class Hamster extends Rodent {
@Override
public void eat() {
System.out.println("Hamster eat...");
}
@Override
public void sleep() {
System.out.println("Hamster sleep...");
}
}
public class Exercise809 {
public static void main(String[] args) {
Rodent[] rd = {
new Mouse(),
new Gerbil(),
new Hamster()
};
for (Rodent rodent : rd) {
rodent.eat();
rodent.sleep();
}
}
}
10.
/**
* 練習10:建立一個包含兩個方法的基類。在第一個方法中可以呼叫第二個
* 方法。然後產生一個繼承自該基類的匯出類,且覆蓋基類中的第二個方法。
* 為該匯出類建立一個物件,將它向上轉型到基型別並呼叫第一個方法,解
* 釋發生的情況。
* @author admin11
* @date 2018年3月28日
*/
class TwoMethods {
public void m1() {
System.out.println("Inside m1, calling m2");
m2();
}
public void m2() {
System.out.println("Inside m2");
}
}
public class Exercise810 extends TwoMethods{
public void m2() {
System.out.println("Inside Exercise810.m2");
}
public static void main(String[] args) {
TwoMethods t = new Exercise810();
t.m1();
// 呼叫匯出類的m1()方法,m1()方法呼叫了m2,
// m2在匯出類被重寫了
}
}
11.
/**
* 練習11:向Sandwich.java中新增Pickle類。
* @author admin11
* @date 2018年3月30日
*/
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()");
}
}
class Pickle {
Pickle() {
System.out.println("Pickle()");
}
}
public class Sandwich extends PortableLunch {
private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();
private Pickle p = new Pickle();
public Sandwich() {
System.out.println("Sandwich()");
}
public static void main(String[] args) {
new Sandwich();
}
}
12.
/**
* 練習12:修改練習9,使其能夠演示基類和匯出類的初始化順序。然後
* 向基類和匯出類中新增成員物件,並說明構建期間初始化發生的順序。
* @author admin11
* @date 2018年3月30日
*/
class Member {
public Member(String id) {
System.out.println("Member constructor " + id);
}
}
class Rodent2 {
Member m1 = new Member("r1"),
m2 = new Member("r2");
public Rodent2() {
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 Mouse2 extends Rodent2 {
Member m1 = new Member("m1"),
m2 = new Member("m2");
public Mouse2() {
System.out.println("Mouse2 constructor");
}
public void hop() {
System.out.println("Mouse2 hopping");
}
public void scurry() {
System.out.println("Mouse2 scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Mice");
}
@Override
public String toString() {
return "Mouse";
}
}
class Gerbil2 extends Rodent2 {
Member m1 = new Member("g1"),
m2 = new Member("g2");
public Gerbil2() {
System.out.println("Gerbil2 constructor");
}
@Override
public void hop() {
System.out.println("Gerbil2 hopping");
}
@Override
public void scurry() {
System.out.println("Gerbil2 scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Gerbils");
}
@Override
public String toString() {
return "Gerbil";
}
}
class Hamster2 extends Rodent2 {
Member m1 = new Member("h1"),
m2 = new Member("h2");
public Hamster2() {
System.out.println("Hamster constructor");
}
@Override
public void hop() {
System.out.println("Hamster hopping");
}
@Override
public void scurry() {
System.out.println("Hamster scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Hamsters");
}
@Override
public String toString() {
return "Hamster";
}
}
public class Exercise812 {
// 先初始化基類的成員變數,呼叫基類的構造方法;
// 然後初始化匯出類的成員變數,呼叫匯出類的構造方法。
public static void main(String[] args) {
new Hamster2();
}
}
13.
/**
* 練習13:在ReferenceCounting.java中新增一個finalize()
* 方法,用來校驗終止條件。
* @author admin11
* @date 2018年3月30日
*/
class Shared {
private int refcount = 0;
private static int counter = 0;
private int id = counter++;
public Shared() {
System.out.println("Creating " + this);
}
public void addRef() {
refcount++;
}
protected void dispose() {
if(--refcount == 0) {
System.out.println("Disposing " + this);
}
}
protected void finalize() {
if(refcount != 0) {
System.out.println("Error: object is not properly cleaned-up!");
}
}
@Override
public String toString() {
return "Shared" + id;
}
}
class Composing {
private Shared shared;
private static int counter = 0;
private int 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();
}
@Override
public String toString() {
return "Composing " + id;
}
}
public class Exercise813 {
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();
}
System.gc();
new Composing(new Shared());
System.gc();
}
}
14.
/**
* 練習14:修改練習12,使得其某個成員物件變為具有引用計數的共享物件,
* 並證明它可以正確執行。
* @author admin11
* @date 2018年3月30日
*/
class NonSharedMember {
public NonSharedMember(String id) {
System.out.println("Non shared member constructor " + id);
}
}
class SharedMember {
private int refcount;
public void addRef() {
System.out.println("Number of references " + ++refcount);
}
protected void dispose() {
if(--refcount == 0) {
System.out.println("Disposing " + this);
}
}
public SharedMember() {
System.out.println("Shared member constructor");
}
@Override
public String toString() {
return "Shared member";
}
}
class Rodent3 {
private SharedMember m;
NonSharedMember m1 = new NonSharedMember("r1"),
m2 = new NonSharedMember("r2");
public Rodent3(SharedMember sm) {
System.out.println("Rodent constructor");
m = sm;
m.addRef();
}
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 void dispose() {
System.out.println("Disposing " + this);
m.dispose();
}
@Override
public String toString() {
return "Rodent";
}
}
class Mouse3 extends Rodent3 {
NonSharedMember m1 = new NonSharedMember("m1"),
m2 = new NonSharedMember("m2");
public Mouse3(SharedMember sm) {
super(sm);
System.out.println("Mouse constructor");
}
@Override
public void hop() {
System.out.println("Mouse hopping");
}
@Override
public void scurry() {
System.out.println("Mouse scurring");
}
@Override
public