1. 程式人生 > >Thinking in Java 第四版完整版 第九章練習題 介面

Thinking in Java 第四版完整版 第九章練習題 介面

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());
    }
}

這裡寫圖片描述