1.1 抽象过程
程序可以通过添加新类型的对象使其自身适用于某个特定问题。
OOP允许根据问题来描述问题,而不是根据运行解决方案的计算机来描述问题,但是它仍然与计算机有联系:每个对象看起来都有点像一个微型计算机——它具有状态,还有操作,用户可以要求对象执行这些操作。
1.2 每个对象都有一个接口
接口定义了对某一个特定对象所能发出的请求。但是,在程序中必须有满足这些请求的代码。这些代码与隐藏的数据一起构成了实现。
1.3 每个对象都提供服务
程序本身将向用户提供服务,它将通过调用其他对象提供的服务来实现这一目的。你的目标就是去创建(或者最好在现有代码库中寻找)能够提供理想的服务来解决问题的一系列对象。
1.4 被隐藏的具体实现
将程序开发人员按照角色分为类创建者(那些创建新数据类型的程序员)和客户端程序员(那些在其应用中使用数据类型的类消费者)是大有裨益的。
控制访问的第一个存在原因就是让客户端程序员无法触及他们不应该触及的部分——这些部分对数据类型的内部操作来说是必需的,但并不是用户解决特定问题所需的接口的一部分。
控制访问的第二个存在原因就是允许库设计者可以改变类内部的工作方式而不用担心会影响到客户端程序员。
public 表示紧随其后的元素对任何人都是可用的。
private 表示除类型创建者和类型的内部方法之外的任何人都不能访问的元素。
protected关键字与private作用相当,差别仅在于继承的类可以访问protected成员,但是不能访问private成员。
Java还有一种缺省的访问权限,这种权限通常被称为“包访问权限”,因为在这种权限下,类可以访问在同一个包中的其他类的成员,但是在包之外,这些成员如同指定了private一样。
1.5 复用具体实现
新的类可以由任意数量、任意类型的其他对象以任意可以实现新的类中想要的功能的方式所组成。因为是使用现有的类合成新的类,所以这种概念被称为组合,如果组合是动态发生的,那么它通常被称为聚合。
1.6 继承:复用接口
有两种方法可以是基类和导出类产生差异。第一种:直接在导出类中添加新方法。 第二种:改变现有基类的方法的行为,这被称为覆盖(overriding)那个方法.
1.7 伴随多态的可互换对象
在处理类型的层次结构时,经常想把一个对象不当作它所属的特定类型对待,而是将其当作基类的对象来对待。这使得人们可以编写出不依赖于特定类型的代码。
那么编译器是如何实现的呢?
编译器不可能产生传统意义上的函数调用。一个非面向对象编程的编译器产生的函数调用会引起所谓的“前期绑定”。这么做意味着编译器将产生对一个具体函数名字的调用,而链接器将这个调用解析到将要被执行的代码的绝对地址。然而在OOP中,程序知道运行时才能够确定代码的地址,所以当发消息送到一个泛化对象时,必须采用其他机制。
为了解决这个问题,面向对象的程序设计语言采用了“后期绑定”的概念。当面向对象发送消息时,被调用的代码直到运行时才能确定。编译器确保被调用方法的存在,并对调用参数和返回值执行类型检查(无法提供此类保证的语言被称为弱类型的),但是并不知道将执行的确切代码。
为了执行后期绑定,Java使用一小段特殊的代码来替代绝对地址调用。这段代码使用在对象中存储的信息来计算方法体的地址(这个过程将在第7章中详述)。这样,根据这一小段代码的内容,每个对象都可以具有不同的行为表现。当向一个对象发送消息时,该对象能够知道对这条消息应该做些什么。
把将导出类看做是它基类的过程称为“向上转型”。一个面向对象程序肯定会在某处包含向上转型,因为这正是将自己从必须知道确切类型中解放出来的关键。
抽象方法只能在抽象类内部创建,当该类被继承时,抽象方法必须被实现,否则继承类仍然是一个抽象类。
1.8 对象的创建、使用和生命期
1.9 异常处理:处理错误
1.10 并发性
1.11 持久性
1.12 Java与Internet