31 Jan 2017

Thinking in Java

目录:

  1. 对象导论
  2. 一切都是对象
  3. 操作符
  4. 控制执行流程
  5. 初始化与清理
  6. 访问控制权限
  7. 复用类
  8. 多态
  9. 接口
  10. 内部类
  11. 持有对象
  12. 通过异常处理错误
  13. 字符串
  14. 类型信息
  15. 泛型
  16. 数组
  17. 容器深入研究
  18. Java I/O系统
  19. 枚举类型
  20. 注解
  21. 并发
  22. 图形化用户界面

第1章 对象导论

1.1 抽象过程

所有编程语言都提供抽象机制。可以认为,人们所能解决的问题的复杂性直接取决于抽象的类型和质量。
Alan Kay曾经总结了第一个成功的面向对象的语言、同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这些特性表现了一种纯粹的面向对象程序设计方式:

  1. 万物皆为对象
  2. 程序是对象的集合
  3. 每个对象都有自己的由其他对象所构成的存储。????
  4. 每个对象都拥有其类型。按照通用的说法,“每个对象都是某个类的一个实例。”
  5. 某一特定类型的所有对象都可以接受同样的信息。
    Booch对对象提出了一个更加简洁的描述:对象具有状态(内部数据)、行为(由方法产生)和标识(内存地址)。

1.2 每个对象都有一个接口

所有的对象都是唯一的,但同时也是具有相同特性和行为的对象所归属的类的一部分。类描述了具有相同特性(数据元素)和行为(功能)的对象集合,所以一个类实际上就是一个数据类型。OOP程序员可以通过定义类来适应问题,而不再被迫只能使用现有的用来表示机器中存储单元的数据类型。
一旦类被建立,就可以随心所欲地创建类的任意个对象,然后去操作他们。
怎样才能获得有用的对象??每个对象都只能满足某些请求,这些请求由对象的接口所定义,决定接口的便是类型。
接口确定了对某一特定对象所能发出的请求。但是,在程序中必须由满足这些请求的代码。这些代码和隐藏的数据一起构成了实现。在类型中,每一个可能的请求都有一个方法与之关联,当项对象发送请求时, 与之相关联的方法就会被调用。

1.3 每个对象都提供服务

将对象看作“服务提供者”

1.4 被隐藏的具体实现

访问控制:Java用三个关键字在类的内部设定边界: public、 private、 protected。这些访问控制词(access specifier)决定了紧跟其后被定义的东西可以被谁使用

  • public:表示紧跟其后的元素对任何人都是可用的
  • private: 表示除类型创建者和内部方法之外的任何人都不能访问元素。
  • protected: 与private作用相当, 差别仅在于继承的类可以访问protected成员, 但是不能访问private成员。
  • 默认的访问权限(包访问权限):当没有使用任何访问指定词时发挥作用,类可以访问在同一个包中的其他类的成员,但是在包之外, 这些成员如同指定了private一样。

1.5 复用的具体实现

最简单地复用某个类的方式就是直接使用该类的一个对象,也可以将那个类的一个#对象#置于某个新的类中(这种方式称为组合)。我们称其为”创建一个成员对象”。新的类可以由任意数量、 任意类型的其他对象以任意可以实现新的类中想要的功能的方式所组成。如果组合是动态发生的,那么它通常被称为聚合。组合经常被视为“has-a”(拥有)关系。新类的成员对象通常都被声明为private,使得使用新类的客户端程序不能访问它们。这也使得你可以在不干扰现有客户端代码的情况下,修改这些成员。也可以在运行时修改这些成员对象, 以实现动态修改程序的行为。 组合带来了极大的灵活性

1.6 继承

在创建了一个类之后, 即使另一个新类与其具有相似的功能, 你还是得重新创建一个新类。继承让我们能够以现有的类为基础, 复制它, 然后通过添加和修改这个副本来创建新类。
有两种方法可以使基类与导出类产生差异。

  1. 添加新方法, (is-like-a base class,基类无法访问新添加的方法。)
  2. 改变现有基类的方法-覆盖(overriding) (is-a base class,替代原则,导出类对象可以完全替代一个基类对象)

1.7 伴随多态的可互换对象

将一个对象当做其基类的对象来对待而不是当做它所属的特定类型来对待。泛化,OOP中程序知道运行时才能确定代码的地址-后期绑定或动态绑定。 在C++中使用virtual关键字来实现,而在Java中,动态绑定是默认行为, 不需要添加额外的关键字来实现多态。

1.8 单根继承结构

在Java中(事实上还包括除C++以外的所有OOP语言),所有的类最终都继承自单一的基类。在Java中,这个终极基类的名字是Object。
优势:垃圾回收器的实现变得容易得多等等。

1.9 容器

通常来说, 如果不知道在解决某个特定问题时需要多少个对象, 或者它们将存活多久, 那么就不可能知道如何存储这些对象。 如何才能知道需要多少空间来创建这些对象呢?
容器在任何需要时都可以扩充自己以容纳你置于其中的所有东西。因此不需要知道将来会把多少个对象置于容器中,只需要创建一个容器对象, 然后让它处理所有细节。 List(用于存储序列),Map(也被称为关联数组,用来建立对象之间的关联),Set(每种对象类型只持有一个),以及诸如队列、 树、 堆栈等更多的构件。

1.9.1 参数化类型

向上转型,向下转型,参数化类型–范型<类型信息>。例如, 可以用下面的语句来创建一个存储Shape的ArrayList: ArrayList shapes = new ArrayList();

1.10 对象的创建和生命期

  1. C++方式,效率,在编写程序时确定对象的存储空间和生命周期,将对象置于堆栈或静态存储区域来实现。
  2. 动态内存分配方式。Java在被称为堆(heap)的内存池中动态地创建对象。在被需要时才被分配空间,所以需要大量的时间在堆中分配存储空间。每当想要创建新的对象时,就要使用new关键字来构建此对象的动态实例。

1.11 异常处理:处理错误

pass for now

1.12 并发编程

pass for now

第2章 一切都是对象

2.1 用引用操纵对象

引用:遥控器;对象:遥控器。

2.2 必须由你创建所有对象

一旦创建了一个引用,就希望它能与一个新的对象相关联。通常用new操作符来实现这一目的。new 关键字的意思是 “给我一个新对象”
所有的Java对象都存储在堆中。
:一种通用的内存池(位于RAM区)
非RAM存储:如果数据完全存活于程序之外,那么他可以不收程序的任何控制, 在程序没有运行时也可以存在。 其中两个基本的例子是流对象持久化对象。在流对象中, 对象转化称为字节流, 通常被发送给另一个机器。在“持久化对象”中,对象被存放于磁盘上,因此, 即使程序终止, 它们仍可以保持自己的状态。 这种存储方式的技巧在于:把对象转化称可以存放在其他媒介上的事物,在需要时, 可恢复成常规的、 基于RAM的对象。如JDBC和Hibernate的机制

2.3 永远不需要销毁对象

2.3.1 作用域

作用域决定了在其内定义的变量名的可见性和生命周期。在C、C++、Java中, 作用域由花括号的位置决定。在作用域里定义的变量只可用于作用域结束之前。

2.3.2 对象的作用域

Java对象不具备和基本类型一样的生命周期。当用new创建一个Java对象时, 它可以存活于作用域之外,但其引用在作用域终点就消失了。然而这个对象仍继续占据内存空间,通过Java的垃圾回收器来释放这些对象的内存空间.

2.4.1字段和方法

当类个某个成员是基本数据类型时,即使没有进行初始化,Java也会确保它获得一个默认值,然而局部变量得到的值可能是任意值。

2.6.3 static关键字

当声明一个事物是static时,就意味着这个域或方法不会与包含它的类的任何对象关联在一起。这些数据和方法是为整个类而不是类的某个特定对象存在的。
static方法的一个重要用法就是在不创建任何对象的前提下就可以调用它。

2.8.1 注释文档

javadoc:对文档的维护,所有的javadoc命令都是只能在“/*”注释中出现, 和通常一样,注释结束与“/”。

2.9 编码风格

  • 类的首字母要大写
  • 类用驼峰风格命名(即不要使用下划线分隔单词)

4.3.3 逗号操作符

注意是逗号操作符而不是逗号分隔符(逗号用作分隔符时用来分隔函数的不同参数),Java中唯一用到逗号操作符的地方就是for循环的控制表达式。在控制表达式的初始化和步进控制部分, 可以使用一系列由逗号分隔的语句;而且那些语句均会独立执行。eg
for(int i = 1, j = i + 10; i < 5; i++, j = i * 2)

第5章 初始化与清理

5.1 用构造器确保初始化

构造器采用与类相同的名称。“每个方法首字母小写”的编码风格并不适合构造器。

5.4 this关键字

只有当需要明确指出对当前对象的引用, 才需要使用this关键字。this关键字只能在方法内部使用,表示对调用方法的那个对象的引用。

5.4.2 static的含义

了解了this关键字之后,就能更全面地理解static方法的含义。static方法就是没有this的方法。在static方法的内部不能调用非静态方法,反过来则是可行的。可以在没有创建任何对象的前提下, 仅仅通过类本身来调用static方法,这实际上正是static方法的主要用途。

5.5 清理:终结处理和垃圾回收

Java由垃圾回收器负责回收无用对象占据的内存资源。由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道如何释放并非使用new获得的“特殊”的内存区域。为了应对这种情况,Java允许在类中定义一个名为finalize()的方法。 finalize()并不是C++中的析构函数。在C++中,对象一定会被销毁(如果程序中没有缺陷的话);而Java里的对象却并非总是被垃圾回收。或者换句话说:

  1. 对象可能不被垃圾回收。
  2. 垃圾回收并不等于“析构”。
  3. 垃圾回收只与内存有关。
    ?? pass for now

5.8.1 可变参数列表

第6章 访问权限控制

  1. public
  2. protected
  3. 包访问权限(没有关键词,默认)
  4. private

6.3 接口和实现

访问权限的控制常被称为是具体实现的隐藏。把数据和方法包装进类中, 以及具体实现的隐藏, 常共同被称作是封装。

第7章 复用类

  1. 组合(has-a)
  2. 继承(is-a)
  3. 代理

7.1 组合语法

将对象的引用置于新类中即可。

7.2 继承语法

通过关键字extends而实现的,当这么做时, 会自动得到基类中所有的域和方法。

7.8 final关键字

  1. 数据
  2. 方法

第8章 多态

第9章 接口

第10章 内部类

内部类与组合是完全不同的概念。:将类置于其他类的内部。#名字隐藏和组织代码的模式
链接到外部类:内部类还拥有外围类的所有元素的访问权。

10.3 使用.this与.new

如果你需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。 这样产生的引用自动地具有正确的类型。

有时你可能想要告知某些其他对象, 去创建其某个内部类的对象。 要实现此目的, 你必须在new表达式中提供对其他外部类对象的引用,这时需要使用.new语法。


Tags:
Stats: