Thinking in Java 第四版完整版 第九章练习题,记录一下(jdk1.8.0)
1.
package com.test.c09;
/**
* 练习1:修改第八章练习9中的Rodent,使其成为一个抽象类。只要有可能,
* 就将Rodent的方法声明为抽象方法。
* @author admin11
* @date 2018年4月1日
*/
abstract class Rodent {
public abstract void hop();
public abstract void scurry();
public abstract void reproduce();
}
class Mouse extends Rodent {
@Override
public void hop() {
System.out.println("Mouse hopping");
}
@Override
public void scurry() {
System.out.println("Mouse scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Mice");
}
@Override
public String toString() {
return "Mouse";
}
}
class Gerbil extends Rodent {
@Override
public void hop() {
System.out.println("Gerbil hopping");
}
@Override
public void scurry() {
System.out.println("Gerbil scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Gerbils");
}
@Override
public String toString() {
return "Gerbil";
}
}
class Hamster extends Rodent {
@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 Exercise901 {
public static void main(String[] args) {
Rodent[] rodents = {
new Mouse(),
new Gerbil(),
new Hamster()
};
for (Rodent rodent : rodents) {
rodent.hop();
rodent.scurry();
rodent.reproduce();
System.out.println(rodent);
}
}
}
2.
package com.test.c09;
/**
* 练习2:创建一个不包含任何抽象方法的抽象类,并验证我们不能为该类
* 创建任何实例。
* @author admin11
* @date 2018年4月1日
*/
abstract class NoAbstractMethods {
void f() {
System.out.println("f()");
}
}
public class Exercise902 {
public static void main(String[] args) {
// Cannot instantiate the type NoAbstractMethods
// new NoAbstractMethods();
}
}
3.
package com.test.c09;
/**
* 练习3:创建一个基类,让它包含抽象方法print(),并在导出类中覆盖
* 该方法。覆盖后的方法版本可以打印导出类中定义的某个整型变量的值。在
* 定义该变量之处,赋予它非零值。在基类的构造器中调用这个方法。现在,
* 在main()方法中,创建一个导出类对象,然后调用它的print()方法。
* 请解释发生的情形。
* @author admin11
* @date 2018年4月1日
*/
abstract class BaseClass {
public BaseClass() {
print();
}
public abstract void print();
}
class ImportClass extends BaseClass{
public int count = 10;
@Override
public void print() {
System.out.println("count = " + count);
}
}
public class Exercise903 {
public static void main(String[] args) {
new ImportClass().print();
// 该print()方法被调用了两次,第一次是在创建导出类时,
// 调用了基类的构造器,基类的构造器调用了print()方法,
// 变量count此时被赋值成0;第二次是导出类对象调用print()
// 方法,count在导出类中被赋值了。
}
}
4.
package com.test.c09;
/**
* 练习4:创建一个不包含任何方法的抽象类,从它那里导出一个类,并添加一个
* 方法。创建一个静态方法,它可以接受指向基类的引用,将其向下转型到导出类,
* 然后再调用该静态方法。在main()中,展现它的运行情况。然后,为基类中
* 的方法加上abstract声明,这样就不再需要进行向下转型。
* @author admin11
* @date 2018年4月1日
*/
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 {
@Override
public void f() {
System.out.println("Extended2.f()");
}
}
public class Exercise904 {
public static void test1(NoMethods nm) {
((Extended1) nm).f();
}
public static void test2(WithMethods wm) {
wm.f();
}
public static void main(String[] args) {
NoMethods nm = new Extended1();
test1(nm);
WithMethods wm = new Extended2();
test2(wm);
}
}
5.
package com.test.c09.e05;
import com.test.c09.e05.inter.AnInterface;
/**
* 练习5:在某个包内创建一个接口,内含三个方法,然后在另一个包中实现
* 此接口。
* @author admin11
* @date 2018年4月1日
*/
class ImplementInterface implements AnInterface {
@Override
public void f() {
System.out.println("ImplementInterface.f()");
}
@Override
public void g() {
System.out.println("ImplementInterface.g()");
}
@Override
public void h() {
System.out.println("ImplementInterface.h()");
}
}
public class Exercise905 {
public static void main(String[] args) {
ImplementInterface imp = new ImplementInterface();
imp.f();
imp.g();
imp.h();
}
}
package com.test.c09.e05.inter;
public interface AnInterface {
void f();
void g();
void h();
}
6.
package com.test.c09;
import com.test.c09.e05.inter.AnInterface;
/**
* 练习6:证明接口内所有的方法都自动是public的。
* @author admin11
* @date 2018年4月1日
*/
public class Exercise906 implements AnInterface{
// The type Exercise906 must implement the inherited abstract method AnInterface.f()
@Override
public void f() {}
@Override
public void g() {}
@Override
public void h() {}
public static void main(String[] args) {
}
}
7.
package com.test.c09;
/**
* 练习7:修改第八章中的练习9,使Rodent成为一个接口。
* @author admin11
* @date 2018年4月1日
*/
interface Rodent2 {
public abstract void hop();
public abstract void scurry();
public abstract void reproduce();
}
class Mouse2 implements Rodent2 {
@Override
public void hop() {
System.out.println("Mouse hopping");
}
@Override
public void scurry() {
System.out.println("Mouse scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Mice");
}
@Override
public String toString() {
return "Mouse";
}
}
class Gerbil2 implements Rodent2 {
@Override
public void hop() {
System.out.println("Gerbil hopping");
}
@Override
public void scurry() {
System.out.println("Gerbil scurrying");
}
@Override
public void reproduce() {
System.out.println("Making more Gerbils");
}
@Override
public String toString() {
return "Gerbil";
}
}
class Hamster2 implements Rodent2 {
@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 Exercise907 {
public static void main(String[] args) {
Rodent2[] rs = {
new Mouse2(),
new Gerbil2(),
new Hamster2()
};
for (Rodent2 rodent2 : rs) {
rodent2.hop();
rodent2.scurry();
rodent2.reproduce();
System.out.println(rodent2);
}
}
}
8.
package com.test.c09;
/**
* 练习8:在polymorphism.Sandwich.java中,创建接口FastFood
* 并添加合适的方法,然后修改Sandwich以实现FastFood接口。
* @author admin11
* @date 2018年4月1日
*/
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()");
}
}
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()");
}
}
interface FastFood {
void rushOrder();
void gobble();
}
class FastSandwich extends Sandwich implements FastFood {
@Override
public void rushOrder() {
System.out.println("Rushing your sandwich order");
}
@Override
public void gobble() {
System.out.println("Chomp! Snort! Gobble!");
}
}
public class Exercise908 {
public static void main(String[] args) {
FastSandwich burger = new FastSandwich();
System.out.println("Fries with that?");
System.out.println("Super Size?");
burger.rushOrder();
burger.gobble();
}
}
9.
package com.test.c09;
/**
* 练习9:重构Music5.java将在Wind、Percussion和Stringed
* 中的公共方法移入一个抽象类中。
* @author admin11
* @date 2018年4月1日
*/
enum Note {
MIDDLE_C, C_SHARP, B_FLAT;
}
abstract class Instrument {
public void play(Note n) {
System.out.println(this + ".play() " + n);
}
public void adjust() {
System.out.println(this + ".adjust()");
}
public abstract String toString();
}
class Wind extends Instrument {
@Override
public String toString() {
return "Wind";
}
}
class Percussion extends Instrument {
@Override
public String toString() {
return "Percussion";
}
}
class Stringed extends Instrument {
@Override
public String toString() {
return "Stringed";
}
}
class Brass extends Wind {
@Override
public String toString() {
return "Brass";
}
}
class Woodwind extends Wind {
@Override
public String toString() {
return "Woodwind";
}
}
public class Exercise909 {
static void tune(Instrument i) {
i.adjust();
i.play(Note.MIDDLE_C);
}
static void tuneAll(Instrument[] e) {
for (Instrument instrument : e) {
tune(instrument);
}
}
public static void main(String[] args) {
Instrument[] ins = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind()
};
tuneAll(ins);
}
}
10.
package com.test.c09.e10;
/**
* 练习10:修改Music5.java,添加Playable接口。将play()的声明
* 从Instrument中移到Playable中。通过将Playable包括在
* implements列表中,把Playable添加到导出类中。修改tune(),
* 使它接受Playable而不是Instrument作为参数。
* @author admin11
* @date 2018年4月2日
*/
enum Note {
MIDDLE_C, C_SHARP, B_FLAT;
}
interface Instrument {
void adjust();
}
interface Playable {
void play(Note n);
}
class Wind implements Instrument, Playable {
@Override
public void play(Note n) {
System.out.println(this + ".play() " + n);
}
@Override
public void adjust() {
System.out.println(this + ".adjust()");
}
@Override
public String toString() {
return "Wind";
}
}
class Percussion implements Instrument, Playable {
@Override
public void play(Note n) {
System.out.println(this + ".play() " + n);
}
@Override
public void adjust() {
System.out.println(this + ".adjust()");
}
@Override
public String toString() {
return "Percussion";
}
}
class Stringed implements Instrument, Playable {
@Override
public void play(Note n) {
System.out.println(this + ".play() " + n);
}
@Override
public void adjust() {
System.out.println(this + ".adjust()");
}
@Override
public String toString() {
return "Stringed";
}
}
class Brass extends Wind {
@Override
public String toString() {
return "Brass";
}
}
class Woodwind extends Wind {
@Override
public String toString() {
return "Woodwind";
}
}
public class Exercise910 {
static void tune(Playable p) {
p.play(Note.MIDDLE_C);
}
static void tuneAll(Playable[] e) {
for (Playable playable : e) {
tune(playable);
}
}
public static void main(String[] args) {
Playable[] ps = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind()
};
tuneAll(ps);
}
}
11.
package com.test.c09;
/**
* 练习11:创建一个类,它有一个方法用于接受一个String类型的参数,
* 生成的结果是将该参数中的每一对字符进行互换。对该类进行适配,使得
* 它可以用于interfaceprocessor.Apply.process()。
* @author admin11
* @date 2018年4月2日
*/
interface Processor {
String name();
Object process(Object input);
}
class Apply {
public static void process(Processor p, Object s) {
System.out.println("Using Processor " + p.name());
System.out.println(p.process(s));
}
}
class CharacterPairSwapper {
static String swap(String s) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length() - 1; i += 2) {
char c1 = sb.charAt(i);
char c2 = sb.charAt(i + 1);
sb.setCharAt(i, c2);
sb.setCharAt(i + 1, c1);
}
return sb.toString();
}
}
class SwapperAdapter implements Processor {
@Override
public String name() {
return CharacterPairSwapper.class.getSimpleName();
}
@Override
public Object process(Object input) {
return CharacterPairSwapper.swap((String)input);
}
}
public class Exercise911 {
public static void main(String[] args) {
Apply.process(new SwapperAdapter(), "1234");
Apply.process(new SwapperAdapter(), "abcde");
}
}
12.
package com.test.c09;
/**
* 练习12:在Adventure.java中,按照其他接口的样式,增加一个
* CanClimb接口。
* @author admin11
* @date 2018年4月3日
*/
interface CanFight {
void fight();
}
interface CanSwim {
void swim();
}
interface CanFly {
void fly();
}
interface CanClimb {
void climb();
}
class ActionCharacter {
public void fight() {}
}
class Hero extends ActionCharacter
implements CanFight, CanSwim, CanFly, CanClimb {
@Override
public void fly() {}
@Override
public void swim() {}
@Override
public void climb() {}
}
public class Exercise912 {
public static void t(CanFight x) {
x.fight();
}
public static void u(CanSwim x) {
x.swim();
}
public static void v(CanFly x) {
x.fly();
}
public static void w(ActionCharacter x) {
x.fight();
}
public static void x(CanClimb c) {
c.climb();
}
public static void main(String[] args) {
Hero h = new Hero();
t(h);
u(h);
v(h);
w(h);
x(h);
}
}
13.
package com.test.c09;
/**
* 练习13:创建一个接口,并从该接口继承两个接口,然后从后面两个接口
* 多重继承第三个接口。
* @author admin11
* @date 2018年4月3日
*/
interface BaseInterface {
void f();
}
interface IntermediateInterface1 extends BaseInterface {
void f();
}
interface IntermediateInterface2 extends BaseInterface {
void f();
}
interface CombinedInterface extends
IntermediateInterface1, IntermediateInterface2 {
void f();
}
class CombinedImpl implements CombinedInterface {
@Override
public void f() {
System.out.println("CombinedImpl.f()");
}
}
public class Exercise913 {
public static void main(String[] args) {
new CombinedImpl().f();
}
}
14.
package com.test.c09;
/**
* 练习14:创建三个接口,每个接口都包含两个方法。继承出一个接口,它组合
* 了这三个接口并添加了一个新方法。创建一个实现了该新接口并继承了某个具体
* 类的类。现在编写四个方法,每一个都接受这四个接口之一作为参数。在main
* ()方法中,创建这个类的对象,并将其传递给这四个方法。
* @author admin11
* @date 2018年4月3日
*/
interface Interface1 {
void f1();
void g1();
}
interface Interface2 {
void f2();
void g2();
}
interface Interface3 {
void f3();
void g3();
}
interface Multiple
extends Interface1, Interface2, Interface3 {
void h();
}
class Concrete {
String s;
public Concrete(String s) {
this.s = s;
}
}
class All extends Concrete implements Multiple {
public All() {
super("All");
}
@Override
public void f1() {
System.out.println("All.f1()");
}
@Override
public void g1() {
System.out.println("All.g1()");
}
@Override
public void f2() {
System.out.println("All.f2()");
}
@Override
public void g2() {
System.out.println("All.g2()");
}
@Override
public void f3() {
System.out.println("All.f3()");
}
@Override
public void g3() {
System.out.println("All.g3()");
}
@Override
public void h() {
System.out.println("All.h()");
}
}
public class Exercise914 {
static void takes1(Interface1 i) {
i.f1();
i.g1();
}
static void takes2(Interface2 i) {
i.f2();
i.g2();
}
static void takes3(Interface3 i) {
i.f3();
i.g3();
}
static void takesAll(All a) {
a.f1();
a.g1();
a.f2();
a.g2();
a.f3();
a.g3();
a.h();
}
public static void main(String[] args) {
All a = new All();
takes1(a);
takes2(a);
takes3(a);
takesAll(a);
}
}
15.
package com.test.c09.e15;
/**
* 练习15:将前一个练习修改为:创建一个抽象类,并将其继承到一个
* 导出类中。
* @author admin11
* @date 2018年4月3日
*/
interface Interface1 {
void f1();
void g1();
}
interface Interface2 {
void f2();
void g2();
}
interface Interface3 {
void f3();
void g3();
}
interface Multiple
extends Interface1, Interface2, Interface3 {
void h();
}
abstract class Concrete {
String s;
public Concrete(String s) {
this.s = s;
}
}
class All extends Concrete implements Multiple {
public All() {
super("All");
}
@Override
public void f1() {
System.out.println("All.f1()");
}
@Override
public void g1() {
System.out.println("All.g1()");
}
@Override
public void f2() {
System.out.println("All.f2()");
}
@Override
public void g2() {
System.out.println("All.g2()");
}
@Override
public void f3() {
System.out.println("All.f3()");
}
@Override
public void g3() {
System.out.println("All.g3()");
}
@Override
public void h() {
System.out.println("All.h()");
}
}
public class Exercise915 {
static void takes1(Interface1 i) {
i.f1();
i.g1();
}
static void takes2(Interface2 i) {
i.f2();
i.g2();
}
static void takes3(Interface3 i) {
i.f3();
i.g3();
}
static void takesAll(All a) {
a.f1();
a.g1();
a.f2();
a.g2();
a.f3();
a.g3();
a.h();
}
public static void main(String[] args) {
All a = new All();
takes1(a);
takes2(a);
takes3(a);
takesAll(a);
}
}
16.
package com.test.c09;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Random;
import java.util.Scanner;
/**
* 练习16:创建一个类,它将生成一个char序列,适配这个类,使其可以成为
* Scanner对象的一种输入。
* @author admin11
* @date 2018年4月9日
*/
class CharSequence {
private static Random rand = new Random(47);
private static final char[] capitals =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final char[] lowers =
"abcdefghijklmnopqrstuvwxyz".toCharArray();
private static final char[] vowels =
"aeiou".toCharArray();
char[] generate() {
char[] buffer = new char[10];
int idx = 0;
buffer[idx++] = capitals[rand.nextInt(capitals.length)];
for(int i = 0; i < 4; i++) {
buffer[idx++] = vowels[rand.nextInt(vowels.length)];
buffer[idx++] = lowers[rand.nextInt(lowers.length)];
}
buffer[idx] = ' ';
return buffer;
}
}
public class Exercise916 extends CharSequence
implements Readable {
private int count;
public Exercise916(int count) {
this.count = count;
}
@Override
public int read(CharBuffer cb) throws IOException {
if(count-- == 0) {
return -1;
}
char[] buffer = generate();
cb.put(buffer);
return buffer.length;
}
public static void main(String[] args) {
Scanner s = new Scanner(new Exercise916(10));
while(s.hasNext()) {
System.out.println(s.next());
}
}
}
17.
package com.test.c09;
/**
* 练习17:证明在接口中的域隐式地是static和final的。
* @author admin11
* @date 2018年4月9日
*/
interface StaticFinalTest {
String RED = "Red";
}
class Test implements StaticFinalTest {
public Test() {
// The final field StaticFinalTest.RED cannot be assigned
// RED = "blue";
}
}
public class Exercise917 {
public static void main(String[] args) {
System.out.println("StaticFinalTest.RED = " + StaticFinalTest.RED);
}
}
18.
package com.test.c09;
/**
* 练习18:创建一个Cycle接口及其Unicycle、Bicycle和Tricycle
* 实现。对每种类型的Cycle都创建相应的工厂,然后编写代码使用这些工厂。
* @author admin11
* @date 2018年4月10日
*/
interface Cycle {
int wheels();
}
interface CycleFactory {
Cycle getCycle();
}
class Unicycle implements Cycle {
@Override
public int wheels() {
return 1;
}
}
class UnicycleFactory implements CycleFactory {
@Override
public Unicycle getCycle() {
return new Unicycle();
}
}
class Bicycle implements Cycle {
@Override
public int wheels() {
return 2;
}
}
class BicycleFactory implements CycleFactory {
@Override
public Bicycle getCycle() {
return new Bicycle();
}
}
class Tricycle implements Cycle {
@Override
public int wheels() {
return 3;
}
}
class TricycleFactory implements CycleFactory {
@Override
public Tricycle getCycle() {
return new Tricycle();
}
}
public class Exercise918 {
public static void ride(CycleFactory fact) {
Cycle c = fact.getCycle();
System.out.println("Num of wheels: " + c.wheels());
}
public static void main(String[] args) {
ride(new UnicycleFactory());
ride(new BicycleFactory());
ride(new TricycleFactory());
}
}
19.
package com.test.c09;
/**
* 练习19:使用工厂方法来创建一个框架,它可以执行抛硬币和掷骰子功能。
* @author admin11
* @date 2018年4月10日
*/
interface Tossing {
boolean event();
}
interface TossingFactory {
Tossing getTossing();
}
class CoinTossing implements Tossing {
private int events;
private static final int EVENTS = 2;
@Override
public boolean event() {
System.out.println("Coin tossing event " + events);
return ++events != EVENTS;
}
}
class CoinTossingFactory implements TossingFactory {
@Override
public CoinTossing getTossing() {
return new CoinTossing();
}
}
class DiceTossing implements Tossing {
private int events;
private static final int EVENTS = 6;
@Override
public boolean event() {
System.out.println("Dice tossing event " + events);
return ++events != EVENTS;
}
}
class DiceTossingFactory implements TossingFactory {
@Override
public DiceTossing getTossing() {
return new DiceTossing();
}
}
public class Exercise919 {
public static void simulate(TossingFactory fact) {
Tossing t = fact.getTossing();
while(t.event())
;
}
public static void main(String[] args) {
simulate(new CoinTossingFactory());
simulate(new DiceTossingFactory());
}
}