[关闭]
@mSolo 2015-04-25T14:15:36.000000Z 字数 6216 阅读 1681

拜读《Java 编程思想》(上)

Java


第 1 章 对象导论

  1. 抽象过程
    • 某一特定类型的所有对象都可以接收同样的消息
    • 对象具有状态、行为和标识
  2. 每个对象都有一个接口
    • 每个对象都只能满足某些请求,这些请求由对象的接口所定义,决定接口的便是类型
    • 接口,即某一特定对象所能发出的请求
  3. 每个对象都提供服务
  4. 被隐藏的具体实现
    • 角色划分:类创建者和客户端程序员
    • 访问控制:publicprivateprotected包访问权限
  5. 复用具体实现
    • 对象间的关系:组合(has-a),如果组合是动态发生的,那么通常被称为聚合
  6. 继承
    • 类型不仅仅只是描述了作用于一个对象集合上的约束条件,同时还有与其他类型之间的关系
    • 差异:添加新方法、覆盖基类方法
  7. 伴随多态的可互换对象
    • 后期绑定、向上转型
  8. 单根继承结构
  9. 容器
    • 泛型:存储 -> 向上转型;取回时 -> 向下转型(要确切知道所要处理的对象的类型)
  10. 对象的创建和生命期(这是一个挑战!)
    • 动态内存分配
  11. 异常处理:处理错误

第 2 章 一切都是对象

  1. 用引用操纵对象
  2. 必须由你创建所有对象
    • 存储到什么地方:寄存器、堆栈、堆、常量存储和非RAM存储
    • 特例:基本类型(堆栈,变量直接存储"值")
  3. 永远不需要销毁对象
    • 对象的作用域(引用存活于作用域内,对象则可以存活于作用域之外,GC 负责回收处理)
  4. 创建新的数据类型: 类
  5. 方法、参数和返回值
    • 方法决定了一个对象能够接收什么样的消息
  6. 构建一个 Java 程序
    • static 关键字
  7. 你的第一个 Java 程序
  8. 注释和嵌入式文档
  9. 编码风格

第 3 章 操作符

第 4 章 控制执行流程

第 5 章 初始化与清理

  1. 用构造器确保初始化
    • 在 Java 中, "初始化"和"创建"捆绑在一起,两者不能分离。
  2. 方法重载
  3. 默认构造器
    • 没有写构造器?编译器给你造一个。如果有,编译器才不理你!
  4. this 关键字
  5. 清理:终结处理和垃圾回收
    • 对象可能不被垃圾回收、垃圾回收并不等于"析构"
    • 你必须实施清理:还是得明确调用某个恰当的 Java 方法
  6. 成员初始化
    • 编译器为其默认赋值,遇到非基本类型的对象时,仍需显式初始化,另外初始化顺序也是相关的
    • 指定初始化,声明时为其赋值,仍然无法阻止自动初始化的进行
  7. 构造器初始化
    • 无法阻止自动初始化的进行,它将在构造器被调用之前发生
    • 静态数据的初始化
  8. 数组初始化
  9. 枚举类型

第 6 章 访问权限控制

所有优秀的作者,包括那些编写软件的程序员,都清楚其著作的某些部分直至重新创作的时候才变得完美,有时甚至要反复重写多次。……,这正是重构的原动力之一。

  • 如何把变动的事物与保持不变的事物区分开来?
  1. 包: 库单元
    • 定制工具库(包括将代码从调试版改为发布版,比如 debug 包和 debugoff 包)
  2. Java 访问权限修饰词
  3. 接口和实现(封装)
  4. 类的访问权限

第 7 章 复用类

  1. 组合语法
    • 依赖注入:构造器注入、setter注入、接口注入和 Service Locator
  2. 继承语法
    • 初始化基类:总是被(自动)调用,并在导出类构造器之前被调用
  3. 代理
    • 将一个成员对象置于所要构造的类中(就像组合),但与此同时我们在新类中暴露了该成员对象的所有方法(就像继承)(SpaceShipDelegation -> SpaceShipControls)
  4. 结合使用组合和继承
    • 确保正确清理
  5. 在组合与继承之间选择
    • 组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形
    • 有时,允许类的用户直接访问新类中的组合成分是极具意义的;也就是说,将成员对象声明为 public(组装 car),这将有助于客户端程序员了解怎样去使用类
  6. prtected 关键字
    • 继承用语,你应当一直保留"更改底层实现"
  7. 向上转型
    • 如果必须向上转型,则继承是必要的,但如果不需要,则应当好好考虑自己是否需要继承。
  8. final 关键字
  9. 初始化及类的加载

第 8 章 多态

  • 多态通过分离做什么和怎么做,从另一角度将接口和实现分离开来。
  • "实现隐藏"则通过将细节"私有化"把接口和实现分离开来。
  • 多态是一项"将改变的事物与未变的事物分离开来"的重要技术。
  1. 再论向上转型(多态的优点)
  2. 转机
    • 方法调用绑定: Java 中除了 static 方法和 final 方法(private 方法属于 final 方法)之外,其他所有的方法都是后期绑定
    • 缺陷: 直接访问域与静态方法
  3. 构造器和多态
  1. class Glyph {
  2. void draw() { print("Glyph.draw()"); }
  3. Glyph() {
  4. print("Glyph() before draw()");
  5. draw();
  6. print("Glyph() after draw()");
  7. }
  8. class RoundGlyph extends Glyph {
  9. print int radius = 1;
  10. RoundGlyph(int r) {
  11. radius = r;
  12. print("RoundGlyph.RoundGlyph(), radius = " + radius);
  13. }
  14. void draw() {
  15. print("RoundGlyph.draw(), radius = " + radius);
  16. }
  17. }
  18. public class PolyConstructors {
  19. public static void main(String[] args) {
  20. new RoundGlyph(5);
  21. }
  22. }
  23. } /* output:
  24. Glyph() before draw()
  25. RoundGlyph.draw(), radius = 0
  26. Glyph() after draw()
  27. RoundGlyph.RoundGlyph(), radius = 5
  28. */

初始化的实际过程是:
1). 在其他任何事情发生之前,将分配给对象的存储空间初始化成二进制的零;
2). 调用基类构造器。此时,调用被覆盖后的draw()方法,由于步骤 1) 的缘故,此时 radius 为 0;
3). 按照声明的顺序调用成员的初始化方法;
4). 调用导出类的构造器主体;

8.4 协变返回类型
8.5 用继承进行设计

第 9 章 接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法
抽象类,普通类与接口之间的一种中庸之道

  1. 抽象类和抽象方法
    • 抽象类,为它的所有导出类创建一个通用接口,以此表示所有导出类的共同部分,目的是通过这个通用接口操纵一系列类
    • 抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动
  2. 接口
    • 接口使抽象的概念比抽象类更向前迈进了一步
    • 所有实现了该特定接口的类看起来都像这样
    • 接口被用来建立类与类之间的协议
    • 接口不仅仅是一个极度抽象的类,因为它允许程序员通过创建一个能够被向上转型为多种基类的类型,来实现某种类似多重继变种的特性
  3. 完全解耦
    • 创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式
    • 适配器设计模式,接受你已拥有的接口,并产生你所需要的接口
  4. Java 中的多重继承
    • 一个 x 是一个 a 和一个 b 以及一个 c
    • 如果要创建不带任何方法定义和成员变量的基类,那么就该选择接口而不是抽象类。
    • 优先使用类而不是接口
  5. 通过继承来扩展接口(注意名字冲突)
  6. 适配接口
  7. 接口中的域(废弃,改为使用enum)
  8. 嵌套接口
    • 嵌套接口可以被实现为 private(即不允许向上转型)
    • 当实现某个接口时,并不需要实现嵌套在其内部的任何借口
  9. 接口与工厂
    • 工厂方法设计模式,在工厂对象上调用的是创建方法,而该工厂对象将生成接口的某个实现的对象(更优雅的工厂实现方式,使用匿名内部类)

第 10 章 内部类

  1. 创建内部类
  2. 链接到外部类
    • 当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其外围类的所有元素的访问权
  3. 使用.this 与.new
  4. 内部类与向上转型
    • 当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类——某个接口的实现——能够完全不可见,并且不可用
  5. 在方法和作用域内的内部类
  6. 匿名内部类
    • 工厂方法
  1. interface Service {
  2. void method1();
  3. void method2();
  4. }
  5. interface ServiceFactory {
  6. Service getService();
  7. }
  8. class Implementation1 implements Service {
  9. private Implementation1() {}
  10. public void method1() {print("Implementation1 method1");}
  11. public void method2() {print("Implementation1 method2");}
  12. public static ServiceFactory factory =
  13. new ServiceFactory() {
  14. public Service getService() {
  15. return new Implementation1();
  16. }
  17. };
  18. }
  19. class Implementation2 implements Service {
  20. private Implementation2() {}
  21. public void method1() {print("Implementation2 method1");}
  22. public void method2() {print("Implementation2 method2");}
  23. public static ServiceFactory factory =
  24. new ServiceFactory() {
  25. public Service getService() {
  26. return new Implementation2();
  27. }
  28. };
  29. }
  30. public class Factories {
  31. public static void serviceConsumer(ServiceFactory fact) {
  32. Service s = fact.getService();
  33. s.method1();
  34. s.method2();
  35. }
  36. public static void main(String[] args) {
  37. serviceConsumer(Implementation1.factory);
  38. // Implementations are completely interchangeable:
  39. serviceConsumer(Implementation2.factory);
  40. }
  41. }

10.7 嵌套类

如果不需要内部类对象与其外围类之间有联系,那么可以将内部类声明为static,这通常称为嵌套类

10.8 为什么需要内部类

1). 内部类提供了某种进入其外围类的窗口
2). 接口解决了部分问题,而内部类有效地实现了"多重继承",即内部类允许继承多个非接口类型(类或抽象类)
3). 更多特性: 内部类可以有多个实例,可以让多个内部类以不同方式实现同一个接口或继承同一个类

  1. package innerclasses.controller;
  2. import java.util.*;
  3. public class Controller {
  4. private List<Event> eventList = new ArrayList<Event>();
  5. public void addEvent(Event c) { eventList.add(c); }
  6. public void run() {
  7. while(eventList.size() > 0)
  8. // Make a copy so you’re not modifying the list while you’re selecting the elements in it:
  9. for(Event e : new ArrayList<Event>(eventList))
  10. if(e.ready()) {
  11. System.out.println(e);
  12. e.action();
  13. eventList.remove(e);
  14. }
  15. }
  16. }
  17. import innerclasses.controller.*;
  18. public class GreenhouseControls extends Controller {
  19. private boolean light = false;
  20. public class LightOn extends Event {
  21. public LightOn(long delayTime) { super(delayTime); }
  22. public void action() {
  23. // Put hardware control code here to physically turn on the light.
  24. light = true;
  25. }
  26. public String toString() { return "Light is on"; }
  27. }
  28. public class LightOff extends Event {
  29. public LightOff(long delayTime) { super(delayTime); }
  30. public void action() {
  31. // Put hardware control code here to
  32. // physically turn off the light.
  33. light = false;
  34. }
  35. public String toString() { return "Light is off"; }
  36. }
  37. // ...
  38. }
  39. import innerclasses.controller.*;
  40. public class GreenhouseController {
  41. public static void main(String[] args) {
  42. GreenhouseControls gc = new GreenhouseControls();
  43. // Instead of hard-wiring, you could parse configuration information from a text file here:
  44. gc.addEvent(gc.new Bell(900));
  45. Event[] eventList = {
  46. gc.new ThermostatNight(0),
  47. gc.new LightOn(200),
  48. gc.new LightOff(400),
  49. gc.new WaterOn(600),
  50. gc.new WaterOff(800),
  51. gc.new ThermostatDay(1400)
  52. };
  53. gc.addEvent(gc.new Restart(2000, eventList));
  54. if(args.length == 1)
  55. gc.addEvent(
  56. new GreenhouseControls.Terminate(
  57. new Integer(args[0])));
  58. gc.run();
  59. }
  60. }

10.9 内部类的继承

  1. class WithInner {
  2. class Inner {}
  3. }
  4. public class InheritInner extends WithInner.Inner {
  5. //! InheritInner() {} // Won’t compile
  6. InheritInner(WithInner wi) {
  7. wi.super();
  8. }
  9. public static void main(String[] args) {
  10. WithInner wi = new WithInner();
  11. InheritInner ii = new InheritInner(wi);
  12. }
  13. }

10.10 内部类可以被覆盖吗

10.11 局部内部类
10.12 内部类标识符: $

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注