《 Java 编程思想》CH07 复用类

2020-02-18  本文已影响0人  wuxiaobai24

复用代码是 Java 众多引人注目的功能之一。

Java 可以通过创建类来复用代码,要在使用类的时候不破坏现有代码,有两种方式:

组合语法

class Soap {
    private String s;
    Soap() {
        System.out.println("Soup()");
        s = "Constructed";
    }

    @Override
    public String toString() {
        return s;
    }
}

/**
 * Bath
 */
public class Bath {

    private String s1 = "happy",  // 在定义处初始化
                    s2; 
    private Soap soap;
    private int i;
    
    public Bath() {
        System.out.println("Inside Bath()");
        soap = new Soap(); // 在构造函数中初四花 
    }

    @Override
    public String toString() {
        if (s2 == null) {
            s2 = "Joy"; // 惰性初始化
        }
        return s2;
    }

    {
        i = 2; // 实例初始化
    }

    public static void main(String[] args) {
        Bath b = new Bath();
        System.out.println(b);
    }
}

继承语法

代理

代理是指,我们将一个成员对象置于要构造的类中(像组合),但与此同时我们在新类中暴露该成员对象的所有或部分方法(想继承)。

IDEA自动创建代理的过程:

class SpaceShipControls {
    void up(int velocity) {}
    void down(int velocity) {}
    void left(int velocity) {}
    void right(int velocity) {}
    void back(int velocity) {}
    void turboBoost() {}
}


public class SpaceShipDelegation {
    SpaceShipControls spaceShipControls = new SpaceShipControls();

    public void up(int velocity) {
        spaceShipControls.up(velocity);
    }

    public void down(int velocity) {
        spaceShipControls.down(velocity);
    }

    public void left(int velocity) {
        spaceShipControls.left(velocity);
    }

    public void right(int velocity) {
        spaceShipControls.right(velocity);
    }

    public void back(int velocity) {
        spaceShipControls.back(velocity);
    }

    public void turboBoost() {
        spaceShipControls.turboBoost();
    }

    public static void main(String[] args) {
        SpaceShipDelegation spaceShipDelegation = new SpaceShipDelegation();
        spaceShipDelegation.left(1);
    }
}

结合使用组合继承

在组合与继承之间选择

向上转型

class Instrument {
    public void play() {}
    static void tune(Instrument i) {
        i.play();
    }
}

public class Wind extends Instrument {
    public static void main(String[] args) {
        Wind wind = new Wind();
        Instrument.tune(wind); // 传递参数时,用了向上转型
    }
}

final 关键字

final 关键词的含义通常指“无法改变的”,使用这个关键词通常是因为设计和效率的原因。,final 可以用在数据、方法和类上。

final 数据

final 方法

final 类

当将一个类的整体定义为 final 时,就表明该类无法被继承,同时隐式地将所有方法都定义为 final。

初始化及类的加载

package com.company.ch07;

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

public class Beetle extends Insert {
    private int k = printInit("Beetle.k init");
    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }
    private static int x2 = printInit("static Beetle.x2 init");

    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        new Beetle();
    }
}

//    static Insert.x1 init
//    static Beetle.x2 init
//    Beetle constructor
//    i = 9 j = 0
//    Beetle.k init
//    k = 47
//    j = 39

练习

练习1

class Demo {
    public Demo() {
        System.out.println("Demo");
    }
    @Override
    public String toString() {
        return "toString()";
    }
}

/**
 * Ex1
 */
public class Ex1 {
    Demo demo;
    @Override
    public String toString() {
        if (demo == null) {
            demo = new Demo();
        }
        return demo.toString();
    }

    public static void main(String[] args) {
        Ex1 ex1 = new Ex1();
        System.out.println(ex1);
    }
}

练习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()"); }
    @Override
    public String toString() {
        return s;
    }
    public static void main(String[] args) {
        Cleanser cleanser = new Cleanser();
        cleanser.dilute(); cleanser.apply(); cleanser.scrub();
        System.out.println(cleanser);
    }
}

/**
 * Detergent
 */
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 detergent = new Detergent();
        detergent.dilute();
        detergent.apply();
        detergent.scrub();
        detergent.foam();
        System.out.println(detergent);
        Cleanser.main(args);    
    }
}

class NewDetergent extends Detergent {
    public void scrub() {
        append("NewDetergent");
        super.scrub();
    }
    public void sterilize() {
        append("sterilize");
    }

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

// Cleanser dilute() apply()NewDetergent Detergent.scrub() scrub() foam()sterilize
// Cleanser dilute() apply() Detergent.scrub() scrub() foam()
// Cleanser dilute() apply() scrub()

练习3 & 练习4

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

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

/**
 * Cartoon
 */
public class Cartoon extends Drawing{

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

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

// Art
// Drawing

练习5

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

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

class C extends A {
    B b = new B();
    public static void main(String[] args) {
        new C();
    }
}

// A
// B

练习6

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

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

/**
 * Chess
 */
public class Chess extends BoardGame {
    
    Chess() {
        super(11); // 去掉这条语句,会报编译错误
        System.out.println("Chess");
    }
    public static void main(String[] args) {
        new Chess();
    }
}

练习7

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

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

class C extends A {
    B b = new B(1);
    C() {
        super(2);
    }
    public static void main(String[] args) {
        new C();
    }
}

练习8

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

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

练习9

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();
    Root() {
        System.out.println("Root");
    }
}

class Stem extends Root {
    Stem() {
        System.out.println("Stem");
    }

    public static void main(String[] args) {
        new Stem();
    }
}
// Component1
// Component2
// Component3
// Root
// Stem

练习10

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

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

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

class Root {
    Component1 c1 = new Component1(1);
    Component2 c2 = new Component2(2);
    Component3 c3 = new Component3(3);
    Root(int i) {
        System.out.println("Root");
    }
}

class Stem extends Root {
    Stem(int j) {
        super(j);
        System.out.println("Stem");
    }

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

练习11

class DetergentDelegation {
    Detergent detergent = new Detergent();

    public void append(String a) {
        detergent.append(a);
    }

    public void dilute() {
        detergent.dilute();
    }

    public void apply() {
        detergent.apply();
    }

    public void scrub() {
        detergent.scrub();
    }

    public void foam() {
        detergent.foam();
    }

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

练习12

package com.company.ch07;

class Component1 {
    Component1(int i) {
        System.out.println("Component1");
    }
    void dispose() {
        System.out.println("Component1 dispose");
    }
}

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

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

class Root {
    Component1 c1 = new Component1(1);
    Component2 c2 = new Component2(2);
    Component3 c3 = new Component3(3);
    Root(int i) {
        System.out.println("Root");
    }
    void dispose() {
        System.out.println("root dispose");
        c1.dispose();
        c2.dispose();
        c3.dispose();
    }
}

class Stem extends Root {
    Stem(int j) {
        super(j);
        System.out.println("Stem");
    }
    void dispose() {
        System.out.println("Stem dispose");
        super.dispose();
    }
    public static void main(String[] args) {
        Stem stem = new Stem(2);
        try {
            // do something
        } finally {
            stem.dispose();
        }

    }
}
// Component1
// Component2
// Component3
// Root
// Stem
// Stem dispose
// root dispose
// Component1 dispose
// Component2 dispose
// Component3 dispose

练习13

class Plate {
    Plate(int i) {
        System.out.println("Plate");
    }
    void func(int i) {
        System.out.println("func int " + i);
    }
    void func(double d) {
        System.out.println("func double " + d);
    }
    void func(String s) {
        System.out.println("func string " + s);
    }
}

class DinnerPlate extends Plate {
    DinnerPlate(int i) {
        super(i);
        System.out.println("DinnerPlate");
    }
    void func(char c) {
        System.out.println("func char " + c);
    }

    public static void main(String[] args) {
        DinnerPlate dinnerPlate = new DinnerPlate(1);
        dinnerPlate.func('c');
        dinnerPlate.func("hello");
        dinnerPlate.func(1);
        dinnerPlate.func(1.0);
    }
}
// Plate
// DinnerPlate
// func char c
// func string hello
// func int 1
// func double 1.0

练习14

package com.company.ch07;

class Engine {
    public void start() {}
    public void rev() {}
    public void stop() {}
    void 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[] wheels = new Wheel[4];
    public Door left = new Door(), right = new Door();
    
    public Car() {
        for (int i = 0;i < 4; i++) {
            wheels[i] = new Wheel();
        }
    }

    public static void main(String[] args) {
        Car car = new Car();
        car.left.window.rollup();
        car.right.window.rolldown();
        car.wheels[0].inflate(72);
        car.engine.service();
    }
}

练习15

package com.company.ch05;

public class Test {
    protected void func() {}
}
package com.company.ch07;
import com.company.ch05.*;

public class Ex15 extends Test{
    public static void main(String[] args) {
        Ex15 ex15 = new Ex15();
        ex15.func();
    }
}

练习16

class Amphibian {
    void func() {
    }

    static void test(Amphibian amphibian) {
        amphibian.func();
    }
}

public class Frog extends Amphibian {
    public static void main(String[] args) {
        Frog frog = new Frog();
        Amphibian.test(frog);
    }
}

练习17

class Amphibian {
    void func() {
        System.out.println("Amphibian func");
    }

    static void test(Amphibian amphibian) {
        amphibian.func();
    }
}

public class Frog extends Amphibian {

    @Override
    void func() {
        System.out.println("Frog func");
    }

    public static void main(String[] args) {
        Frog frog = new Frog();
        Amphibian.test(frog);
    }
}
// Frog func

练习18

public class Ex18 {
    static Random random = new Random(12);
    final int i = random.nextInt(12);
    static final int j = random.nextInt(12);

    public static void main(String[] args) {
        Ex18 ex18 = new Ex18();
        System.out.println("ex18.i = " + ex18.i);
        System.out.println("ex18.j = " + ex18.j);
        Ex18 ex181 = new Ex18();
        System.out.println("ex181.i = " + ex181.i);
        System.out.println("ex181.j = " + ex181.j);
    }
}
// ex18.i = 8
// ex18.j = 6
// ex181.i = 4
// ex181.j = 6

练习19

public class Ex19 {
    final int k;
    Ex19() {
        k = 1; // 必须赋值
        // k = 2; // 会报错
    }

    public static void main(String[] args) {
        Ex19 ex19 = new Ex19();
        // ex19.k = 1; // 会报错
    }
}

练习20

package com.company.ch07;

class WithFinal {
    private final void f() {
        System.out.println("WithFinal.f()");
    }

    private void g() {
        System.out.println("WithFinal.g()");
    }
}

class OverridingPrivate extends WithFinal {
//    @Override //加上注解后编译错误
    private final void f() {
        System.out.println("OverridingPrivate.f()");
    }
//    @Override //加上注解后编译错误
    private void g() {
        System.out.println("OverridingPrivate.g()");
    }
}

class OverridingPrivate2 extends OverridingPrivate {
//    @Override //加上注解后编译错误
    public final void f() {
        System.out.println("OverridingPrivate2.f()");
    }
//    @Override //加上注解后编译错误
    public void g() {
        System.out.println("OverridingPrivate2.g()");
    }
}

public class FinalOverridingIllusion extends OverridingPrivate2 {
    public static void main(String[] args) {
        OverridingPrivate2 overridingPrivate2 = new OverridingPrivate2();
        overridingPrivate2.f();
        overridingPrivate2.g();

        OverridingPrivate overridingPrivate = overridingPrivate2;
//        overridingPrivate.f(); 无法调用
//        overridingPrivate.g();
        WithFinal withFinal = overridingPrivate;
//        withFinal.f(); 无法调用
//        withFinal.g();
    }
}

练习21

package com.company.ch07;

class Final {
    final void f() {}
}

public class Ex21 extends Final {
    void f() {} // 编译出错
}

练习22

package com.company.ch07;

final class FinalClass {
    
}

public class Ex22 extends FinalClass { //编译出错
}

练习23

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

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

class Ex23 {
    public static void main(String[] args) {
        new Beetle();
//        static Insert.x1 init
//        static Beetle.x2 init
//        i = 9 j = 0
//        Beetle.k init
//        k = 47
//        j = 39
        // or
        // System.out.println(Beetle.x3);
//        static Insert.x1 init
//        static Beetle.x2 init
//        3
    }
}

练习24

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

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

class Ex24 extends Beetle {
    public static void main(String[] args) {
        new Ex24();
//        static Insert.x1 init
//        static Beetle.x2 init
//        i = 9 j = 0
//        Beetle.k init
//        k = 47
//        j = 39
    }
}
  1. 调用 Ex24 的main函数(静态方法),准备加载 Ex24,但是发现其继承与 Beetle
  2. 准备加载 Beetle,但是发现其继承与 Insert,因此先加载 Insert
  3. Insert 中的静态数据先初始化,所以会输出static Insert.x1 init
  4. Insert 加载并初始化完后,加载 Beetle 并对静态数据进行初始化,所以会输出static Beetle.x2 init
  5. 然后加载 Ex24,加载过程完成,调用 main 函数
  6. new Ex24时,实例化的顺序为 Insert -> Beetle -> Ex24
  7. 所以先输出 Insert 构造函数中的 i = 9 j = 0,之所以 j 为0,是因为int默认值为0
  8. 然后在实例化 Beetle 时,先会执行 实例初始化,即private int k = printInit("Beetle.k init");
  9. 最后才是 Beetle 的构造函数。

本文首发于Code & Fun

上一篇下一篇

猜你喜欢

热点阅读