Thinking in Java 第四版完整版 第七章练习题 复用类

Thinking in Java 第四版完整版 第七章练习题,记录一下(jdk1.8.0)

1.

/**
 * 练习1:创建一个简单的类。在第二个类中,将一个引用定义为第一个类
 * 的对象。运用惰性初始化来实例化这个对象。
 * @author admin11
 * @date 2018年3月21日
 */

class Simple {
    String s;
    public Simple(String si) {
        s = si;
    }

    public String toString() {
        return s;
    }

    public void setString(String sNew) {
        s = sNew;
    }
}

class Second {
    Simple simple;
    String s;

    public Second(String si) {
        s = si;
    }

    public void check() {
        if(simple == null) {
            System.out.println("not initialized");
        } else {
            System.out.println("initialized");
        }
    }

    private Simple lazy() {
        if(simple == null) {
            System.out.println("Creating Simple");
            simple = new Simple(s);
        }
        return simple;
    }

    public Simple getSimple() {
        return lazy();
    }

    public String toString() {
        return lazy().toString();
    }

    public void setSimple(String sNew) {
        lazy().setString(sNew);
    }
}

public class Exercise701 {

    public static void main(String[] args) {
        Second second = new Second("Init String");
        second.check();
        System.out.println(second.getSimple());
        second.check();
        System.out.println(second);
        second.setSimple("New String");
        System.out.println(second);
    }
}

这里写图片描述

2.

class Cleanser {
    private String s = "Cleanser ";
    public void append(String a) {
        s += a;
    }

    public void dilute() {
        append("dilute() ");
    }

    public void apply() {
        append("apply() ");
    }

    public void scrub() {
        append("scrub() ");
    }

    public String toString() {
        return s;
    }

    public static void main(String[] args) {
        Cleanser x = new Cleanser();
        x.dilute();
        x.apply();
        x.scrub();
        System.out.println(x);
    }
}

public class Detergent extends Cleanser{

    @Override
    public void scrub() {
        append("Detergent.scrub()");
        super.scrub();
    }

    public void foam() {
        append("foam()");
    }

    public static void main(String[] args) {
        Detergent x = new Detergent();
        x.dilute();
        x.apply();
        x.scrub();
        x.foam();
        System.out.println(x);
        Cleanser.main(args);
    }
}

这里写图片描述

/**
 * 练习2:从Detergent中继承产生一个新的类。覆盖scrub()
 * 并添加一个名为sterilize()的新方法。
 * @author admin11
 * @date 2018年3月21日
 */
public class Exercise702 extends Detergent{

    @Override
    public void scrub() {
        append("Exercise702.scrub()");
    }

    public void sterilize() {
        append("Exercise702.sterilize()");
    }

    public static void main(String[] args) {
        Exercise702 e = new Exercise702();
        e.dilute();
        e.apply();
        e.scrub();
        e.sterilize();
        System.out.println(e);
    }
}

这里写图片描述

3.

class Art {
    Art() {
        System.out.println("Art constructor");
    }
}

class Drawing extends Art {
    Drawing() {
        System.out.println("Drawing constructor");
    }
}

public class Cartoon extends Drawing {

    public Cartoon() {
        System.out.println("Cartoon constructor");
    }

    public static void main(String[] args) {
        Cartoon x = new Cartoon();
    }
}

这里写图片描述

/**
 * 练习3:证明前面这句话。
 * @author admin11
 * @date 2018年3月22日
 */
public class Exercise703 extends Drawing{

    /*即使你不为Cartoon()创建构造器,编译器也会为你合成一个
     * 默认的构造器,该构造器将调用基类的构造器。*/
    public static void main(String[] args) {
        Exercise703 e = new Exercise703();
    }
}

这里写图片描述

4.

/**
 * 练习4:证明基类构造器:(a)总是会被调用;
 * (b)在导出类构造器之前被调用。
 * @author admin11
 * @date 2018年3月22日
 */

class Base1 {
    public Base1() {
        System.out.println("Base1");
    }
}

class Derived1 extends Base1 {
    public Derived1() {
        System.out.println("Derived1");
    }
}

class Derived2 extends Derived1 {
    public Derived2() {
        System.out.println("Derived2");
    }
}

public class Exercise704 {

    public static void main(String[] args) {
        new Derived2();
    }
}

这里写图片描述

5.

/**
 * 练习5:创建两个带有默认构造器(空参数列表)的类A和类B。
 * 从A中继承产生一个名为C的新类,并在C内创建一个B类的成员。
 * 不要给C编写构造器。创建一个C类的对象并观察其结果。
 * @author admin11
 * @date 2018年3月22日
 */

class A {
    public A() {
        System.out.println("A()");
    }
}

class B {
    public B() {
        System.out.println("B()");
    }
}

class C extends A {
    B b = new B();
}

public class Exercise705 {

    public static void main(String[] args) {
        new C();
    }
}

这里写图片描述

6.

/**
 * 练习6:用Chess.java来证明前一段话。
 * @author admin11
 * @date 2018年3月26日
 */
// 如果不在BoardGame()中调用基类构造器,编译器将“抱怨”无法找到
// 符合Game()形式的构造器。而且,调用基类构造器必须是你在导出类构
// 造器中要做的第一件事(如果你做错了,编译器会提醒你的)。
class Game {
    Game(int i) {
        System.out.println("Game constructor");
    }
}

class BoardGame extends Game {
    BoardGame(int i) {
        super(i);
        System.out.println("BoardGame constructor");
    }
}

public class Chess extends BoardGame {
    Chess() {
        super(11);
        System.out.println("Chess constructor");
    }

    public static void main(String[] args) {
        Chess x = new Chess();
    }
}

这里写图片描述
这里写图片描述

7.

/**
 * 练习7:修改练习5,使A和B以带参数的构造器取代默认的构造器。
 * 为C写一个构造器,并在其中执行所有的初始化。
 * @author admin11
 * @date 2018年3月26日
 */
class A {
    public A(String str) {
        System.out.println("A() " + str);
    }
}

class B {
    public B(String str) {
        System.out.println("B() " + str);
    }
}

class C extends A {
    B b;
    public C(String str) {
        super(str);
        b = new B(str);
    }
}

public class Exercise707 {

    public static void main(String[] args) {
        new C("string");
    }
}

这里写图片描述

8.

/**
 * 练习8:创建一个基类,它仅有一个非默认构造器;再创建一个导出类,
 * 它带有默认构造器和非默认构造器。在导出类的构造器中调用基类的构造器。
 * @author admin11
 * @date 2018年3月27日
 */

class Base {
    public Base(int i){
        System.out.println("Base " + i);
    }
}

public class Exercise708 extends Base {

    public Exercise708() {
        super(12);
    }

    public Exercise708(int i) {
        super(i);
    }

    public static void main(String[] args) {
        new Exercise708();
        new Exercise708(20);
    }
}

这里写图片描述

9.

/**
 * 练习9:创建一个Root类,令其含有名为Component1、Component2
 * Component3的类的各一个实例(这些也由你写)。从Root中派生一个类
 * Stem,也含有上述各“组成部分”。所有的类都应带有可打印出类的相关信息
 * 的默认构造器。
 * @author admin11
 * @date 2018年3月27日
 */

class Component1 {
    Component1() {
        System.out.println("Component1");
    }
}

class Component2 {
    Component2() {
        System.out.println("Component2");
    }
}

class Component3 {
    Component3() {
        System.out.println("Component3");
    }
}

class Root {
    Component1 c1 = new Component1();
    Component2 c2 = new Component2();
    Component3 c3 = new Component3();
    public Root() {
        System.out.println("Root");
    }
}

class Stem extends Root {
    Component1 c1 = new Component1();
    Component2 c2 = new Component2();
    Component3 c3 = new Component3();
    public Stem() {
        System.out.println("Stem");
    }
}

public class Exercise709 {

    public static void main(String[] args) {
        new Stem();
    }
}

这里写图片描述

10.

/**
 * 练习10:修改练习9,使每个类都仅具有非默认的构造器。
 * @author admin11
 * @date 2018年3月27日
 */

class Component1 {
    Component1(String str) {
        System.out.println("Component1 " + str);
    }
}

class Component2 {
    Component2(String str) {
        System.out.println("Component2 " + str);
    }
}

class Component3 {
    Component3(String str) {
        System.out.println("Component3 " + str);
    }
}

class Root {
    Component1 c1 = new Component1("Root");
    Component2 c2 = new Component2("Root");
    Component3 c3 = new Component3("Root");
    public Root(String str) {
        System.out.println("Root " + str);
    }
}

class Stem extends Root {
    Component1 c1 = new Component1("Stem");
    Component2 c2 = new Component2("Stem");
    Component3 c3 = new Component3("Stem");
    public Stem(String str) {
        super(str);
        System.out.println("Stem " + str);
    }
}

public class Exercise710 {

    public static void main(String[] args) {
        new Stem("hi");
    }
}

这里写图片描述

11.

/**
 * 练习11:修改Detergent.java,让它使用代理。
 * @author admin11
 * @date 2018年3月27日
 */

class Cleanser {
    public Cleanser() {
        System.out.print("Cleanser");
    }

    public void append(String str) {
        System.out.print(" " + str);
    }
    public void dilute() {
        System.out.print(" dilute()");
    }
    public void apply() {
        System.out.print(" apply()");
    }
    public String toString() {
        return "";
    }
    public void scrub() {
        System.out.print(" scrub()");
    }
    public static void main(String[] args) {
        Cleanser c = new Cleanser();
        c.dilute();
        c.apply();
        c.scrub();
    }
}

class DetergentDelegation {
    private Cleanser cleanser = new Cleanser();
    public void append(String a) {
        cleanser.append(a);
    }
    public void dilute() {
        cleanser.dilute();
    }
    public void apply() {
        cleanser.apply();
    }
    public String toString() {
        return cleanser.toString();
    }
    public void scrub() {
        append(" DetergentDelegation.scrub()");
        cleanser.scrub();
    }
    public void foam() {
        append(" foam()");
    }

    public static void main(String[] args) {
        DetergentDelegation x = new DetergentDelegation();
        x.dilute();
        x.apply();
        x.scrub();
        x.foam();
        System.out.println(x);
        System.out.println("Testing base class:");
        Cleanser.main(args);
    }
}

public class Exercise711 {

    public static void main(String[] args) {
        DetergentDelegation.main(args);
    }
}

这里写图片描述

12.

/**
 * 练习12:将一个适当的dispose()方法的层次结构添加到练习9的所有
 * 类中。
 * @author admin11
 * @date 2018年3月27日
 */
class Component1 {
    public Component1() {
        System.out.println("Component1");
    }
    public void dispose() {
        System.out.println("Component1 dispose");
    }
}

class Component2 {
    public Component2() {
        System.out.println("Component2");
    }
    public void dispose() {
        System.out.println("Component2 dispose");
    }
}

class Component3 {
    Component3() {
        System.out.println("Component3");
    }
    public void dispose() {
        System.out.println("Component3 dispose");
    }
}

class Root {
    Component1 c1 = new Component1();
    Component2 c2 = new Component2();
    Component3 c3 = new Component3();
    public Root() {
        System.out.println("Root");
    }
    public void dispose() {
        System.out.println("Root dispose");
        c3.dispose();
        c2.dispose();
        c1.dispose();
    }
}

class Stem extends Root {
    Component1 c1 = new Component1();
    Component2 c2 = new Component2();
    Component3 c3 = new Component3();
    public Stem() {
        super();
        System.out.println("Stem");
    }
    public void dispose() {
        System.out.println("Stem dispose");
        c3.dispose();
        c2.dispose();
        c1.dispose();
        super.dispose();
    }
}

public class Exercise712 {

    public static void main(String[] args) {
        new Stem().dispose();
    }
}

这里写图片描述

13.

/**
 * 练习13:创建一个类,它应带有一个被重载了三次的方法。继承产生一个新类,
 * 并添加一个该方法的新的重载定义,展示这四个方法在导出类中都是可以使用的。
 * @author admin11
 * @date 2018年3月27日
 */
class Animal {
    public void eat() {
        System.out.println("eat...");
    }
    public void eat(int i) {
        System.out.println("eat meat...");
    }
    public void eat(String str) {
        System.out.println("eat leaf...");
    }
}

public class Exercise713 extends Animal {
    public void eat(double d) {
        System.out.println("eat double...");
    }

    public static void main(String[] args) {
        Exercise713 e = new Exercise713();
        e.eat();
        e.eat("hi");
        e.eat(100);
        e.eat(2.3);
    }
}

这里写图片描述

14.

/**
 * 练习14:在Car.java中给Engine添加一个service()方法,
 * 并在main()中调用该方法。
 * @author admin11
 * @date 2018年3月27日
 */
class Engine {
    public void start() {}
    public void rev() {}
    public void stop() {}
    public void service() {
        System.out.println("service...");
    }
}

class Wheel {
    public void inflate(int psi) {}
}

class Window {
    public void rollup() {}
    public void rolldown() {}
}

class Door {
    public Window window = new Window();
    public void open() {}
    public void close() {}
}

public class Car {
    public Engine engine = new Engine();
    public Wheel[] wheel = new Wheel[4];
    public Door 
        left = new Door(),
        right = new Door();
    public Car() {
        for (int i = 0; i < 4; i++) {
            wheel[i] = new Wheel();
        }
    }
    public static void main(String[] args) {
        Car car = new Car();
        car.left.window.rollup();
        car.wheel[0].inflate(72);
        car.engine.service();
    }
}

这里写图片描述

15.

public class Exercise715_pro {

    protected void f() {
        System.out.println("f()");
    }
}
import com.test.c07.e15.Exercise715_pro;

/**
 * 练习15:在包中编写一个类,类应具备一个protected方法。在包外部,
 * 试着调用该protected方法并解释其结果。然后,从你的类中继承产生
 * 一个类,并从该导出类的方法内部调用该protected方法。
 * @author admin11
 * @date 2018年3月27日
 */
class Derived extends Exercise715_pro {
    public void g() {
        f();
    }
}

public class Exercise715_test {

    public static void main(String[] args) {
        // The method f() from the type Exercise715_pro is not visible
        // new Exercise715_pro().f(); 
        new Derived().g();
    }
}

这里写图片描述

16.

/**
 * 练习16:创建一个名为Amphibian的类。由此继承产生一个称为Frog的
 * 类。在基类中设置适当的方法。在main()中,创建一个Frog并向上转型
 * 至Amphibian,然后说明所有方法都可工作。
 * @author admin11
 * @date 2018年3月27日
 */
class Amphibian {
    public void moveInWater() {
        System.out.println("Moving in Water");
    }
    public void moveOnLand() {
        System.out.println("Moving on Land");
    }
}

class Frog extends Amphibian {}

public class Exercise716 {

    public static void main(String[] args) {
        Amphibian a = new Frog();
        a.moveInWater();
        a.moveOnLand();
    }
}

这里写图片描述

17.

/**
 * 练习17:修改练习16,使Frog覆盖基类中方法的定义(令新定义使用相同
 * 的方法特征签名)。请留心main()中都发生了什么。
 * @author admin11
 * @date 2018年3月27日
 */
class Frog2 extends Amphibian {
    @Override
    public void moveInWater() {
        System.out.println("frog in Water");
    }
    @Override
    public void moveOnLand() {
        System.out.println("frog on Land");
    }
}

public class Exercise717 {

    public static void main(String[] args) {
        Amphibian a = new Frog2();
        a.moveInWater();
        a.moveOnLand();
    }
}

这里写图片描述

18.

/**
 * 练习18:创建一个含有static final域和final域的类,说明二者间的区别。
 * @author admin11
 * @date 2018年3月27日
 */
class SelfCounter {
    private static int count;
    private int id = count++;
    public String toString() {
        return "SelfCounter " + id;
    }
}

class WithFinalFields {
    final SelfCounter scf = new SelfCounter();
    static final SelfCounter scsf = new SelfCounter();
    public String toString() {
        return "scf = " + scf + "\nscsf = " + scsf;
    }
}

public class Exercise718 {
    // 因为类装载初始化了static final类型的变量,所以在两次
    // 创建WithFinalFields实例时都具有相同的值。而常规的final
    // 的值在每一个实例中都是不同的。
    public static void main(String[] args) {
        System.out.println("First object:");
        System.out.println(new WithFinalFields());
        System.out.println("Second object:");
        System.out.println(new WithFinalFields());
    }
}

这里写图片描述

19.

/**
 * 练习19:创建一个含有指向某对象的空白final引用的类。在所有构造器
 * 内部都执行空白final的初始化动作。说明Java确保final在使用前
 * 必须被初始化,且一旦被初始化即无法改变。
 * @author admin11
 * @date 2018年3月27日
 */
class WithBlankFinalField {
    private final Integer i;
    // The blank final field i may not have been initialized
    public WithBlankFinalField(int cnt) {
        i = new Integer(cnt);
    }

    public Integer geti() {
        // The final field WithBlankFinalField.i cannot be assigned
//      if(i == null)
//          i = new Integer(47);
        return i;
    }
}

public class Exercise719 {

    public static void main(String[] args) {
        WithBlankFinalField w = new WithBlankFinalField(10);
        System.out.println(w.geti());
    }
}

这里写图片描述

20.

/**
 * 练习20:展示@Override注解可以解决本节中的问题。
 * @author admin11
 * @date 2018年3月27日
 */
class WithFinals {
    private final void f() {
        System.out.println("WithFinals.f()");
    }
    public void g() {
        System.out.println("WithFinals.g()");
    }
}

class OverridingPrivate extends WithFinals{
    private final void f() {
        System.out.println("OverridingPrivate.f()");
    }
    public void g() {
        System.out.println("OverridingPrivate.g()");
    }
}

class OverridingPrivate2 extends OverridingPrivate {
    public final void f() {
        System.out.println("OverridingPrivate2.f()");
    }
    public void g() {
        System.out.println("OverridingPrivate2.g()");
    }
}

public class Exercise720 {

    public static void main(String[] args) {
        OverridingPrivate2 op2 = new OverridingPrivate2();
        op2.f();
        op2.g();
    }
}

这里写图片描述

21.

/**
 * 练习21:创建一个带final方法的类。由此继承产生一个类并尝试
 * 覆盖该方法。
 * @author admin11
 * @date 2018年3月27日
 */
class WithFinalMethod {
    final void f() {}
}

public class Exercise721 extends WithFinalMethod{
    // Cannot override the final method from WithFinalMethod
    // void f() {}
}

22.

/**
 * 练习22:创建一个final类并试着继承它。
 * @author admin11
 * @date 2018年3月27日
 */
final class FinalClass {}
// The type Exercise722 cannot subclass 
// the final class FinalClass
public class Exercise722 extends FinalClass {
    // final类不能被继承
}

23.

/**
 * 练习23:请证明加载类的动作仅发生一次。证明该类的第一个实体的创建
 * 或者对static成员的访问都有可能引起加载。
 * @author admin11
 * @date 2018年3月27日
 */
class LoadTest {
    static {
        System.out.println("Loading LoadTest");
    }
    static void staticMember() {}
}

public class Exercise723 {

    public static void main(String[] args) {
        System.out.println("Calling static member");
        LoadTest.staticMember();
        System.out.println("Creating an object");
        new LoadTest();
    }
}

这里写图片描述

24.

class Insect {
    private int i = 9;
    protected int j;
    Insect() {
        System.out.println("i = " + i + ", j = " + j);
        j = 39;
    }
    private static int x1 = printInit("static Insect.x1 initialized");
    static int printInit(String s) {
        System.out.println(s);
        return 47;
    }
}

public class Beetle extends Insect {
    private int k = printInit("Beetle.k initialized");
    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }
    private static int x2 = printInit("static Beetle.x2 initialized");
    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

这里写图片描述

/**
 * 练习24:在Beetle.java中,从Beetle类继承产生一个具体类型
 * 的“甲壳虫”。其形式与现有类相同,跟踪并解释其输出结果。
 * @author admin11
 * @date 2018年3月27日
 */
public class Exercise724 extends Beetle {
    int m = printInit("Exercise724.m initialized");
    public Exercise724() {
        System.out.println("m = " + m);
        System.out.println("j = " + j);
    }
    static int x3 = printInit("static Exercise724.x3 initialized");

    public static void main(String[] args) {
        new Exercise724();
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/summerSunStart/article/details/79718231