1)抽象过程
人们所能够解决问题的复杂性直接取决于抽象的类型和质量。
汇编语言是对底层机器的轻微抽象,接着出现许多所谓“命令式”语言(basic,c)都是对汇编语言的抽象,这些语言在汇编基础上有了大幅度的改进,但是它们所作的主要抽象仍然要求在解决问题时要基于计算机结构,而不是基于所要解决的问题的结构来考虑。开发者必须建立在机器模型和实际待解决问题的模型之间的关联,建立这种映射是费力的,而且这不属于编程语言所固有的功能,这使得程序难以编写,维护代价高昂等。不过这些抽象方式对于它们所要解决的特定类型的问题都是不错的解决方案,但是一旦超出其特定领域,它们就力不从心了。
对比而言,面向对象的方式,程序可以通过添加新类型的对象使自身使用于某个特定问题.。OOP允许根据问题来描述问题,而不是根据允许解决方案的计算机来描述问题。但是它仍然与计算机有联系:每个对象看起来都有点像一台微型计算机----它具有状态,操作,用户可以要求对象执行这些操作。
2)万物皆对象
理论上讲,你可以抽取待求解问题的任何概念化构建(狗、建筑物、服务等),将其表示为程序中的对象。
3)每个对象都拥有其类型
每个类最重要的区别于其他类的特性就是“可以发送什么样的消息给它”。
4)某一特定类型的所有对象都可以接收同样的消息
因为 “圆形” 类型的对象 同时也是 “几何形” 类型的对象,所以一个 “圆形” 对象必定能接收发送给 “几何形” 的消息。
5)对象的简洁描述
对象具有状态、行为、和标识。这意味着 每一个对象都可以拥有内部数据(她们给出了对象的状态)和方法(它们产生行为),并且每一个对象都可以唯一的与其他对象区分开来,具体的说,就是每一个对象在内存中都有一个唯一的地址。
6)抽象数据类型(类)
抽象数据类型的运行方式与内置类型几乎完全一致:你可以创建某一类型的变量(按照面向对象的说法,称其为对象或实例),然后操作这些变量(称其为发送消息或请求,对象就知道要做什么)。
因为类描述了具有相同特性(数据元素)和行为(功能)的对象集合,所以一个类实际上就是一个数据类型,例如所有浮点型数字具有相同的特性和行为集合。二者的差异在于,程序员通过定义类来适应问题,而不再被迫只能使用现有的用来表示机器中的存储单元的数据类型。可以根据需求,通过添加新的数据类型来扩展编程语言,编程系统欣然接受新的类,并且像对待内置类型一样的照管它们和进行类型检查。
7)方法
隶属于此对象的、用来接收你发给此对象的消息的函数
8)每个对象都提供服务
当正在试图开发或理解一个程序设计时,最好的方法之一就是将对象想象为 “服务提供者” 。程序本身将向用户提供服务,它将通过调用其他对象提供的服务来实现这一目的。你的目的就是去创建(或者最好是在现有的代码库中寻找)能够提供理想的服务来解决问题的一系列对象。
将对象作为服务提供者看待是一件伟大的简化工具,这不仅在设计过程中非常有用,而且当其他人试图理解你的代码或重用某个对象时,如果他们看出了这个对象所能提供的服务的价值,它会使得调整对象以适应其设计的过程变得简单的多。
9)被隐藏的具体实现
客户端程序员的目标是收集各种用来实现快速应用开发的类。类创建者的目标是构建类。这种类只向客户端程序员暴露必需的部分,而隐藏其他部分。为什么要这样呢?因为加以隐藏,那么客户端程序员将不能访问它,这意味着类创建者可以任意的修改被隐藏的部分,而不用担心对其他人造成音响。被隐藏的部分通常代表对象内部脆弱的部分,它们容易被粗心的或不知内情的客户端程序员所毁坏,因此将隐藏实现起来可以减少程序bug
10)访问控制
访问控制存在的原因一:就是让客户端程序员无法触及他们不该触及的部分----这些部分对数据类型的内部操作来说是必需的,但并不是用户解决特定问题所需的接口的一部分。这对于客户端程序员来说其实是一项服务,因为他们可以很容易的看出哪些东西对他们来说很重要,而哪些东西可以忽略。
访问控制存在的原因二:就是允许库设计者可以改变类内部的工作方式而不用担心会影响到客户端程序员。例如:你可能为了减轻开发任务而以某种简单的方式实现了某个特定的类,但稍后发现你必须改写他才能使其允许的更快。如果接口和实现可以清晰的分离并得以保护,那么你就可以轻而易举的完成这项工作。
11)继承
继承使用基类型和导出类型的概念表示了这种类型之间的相似性。一个基类型包含所有导出类所共享的特性和行为。可以创建一个基类型来表示系统中某些对象的核心概念,从基类型中导出其他类型,来表示此核心可以被实现的各种不同方式。
12)覆盖
你可以说 “此时,我正在使用相同的接口方法,但是我想在新类型中做一些不同的事情”。
13)后期绑定
面向对象程序设计语言使用了后期绑定的概念。当向对象发送消息时,被调用的代码直到运行时才能确定,编译器确保被调用方法的存在,并对调用参数和返回值执行类型检查,但并不知道将被执行的确切代码。
14)向上转型
当Circle被传入预期接收Shape的方法中,究竟会发生什么?由于Circle可以被看作是Shape,也就是说发送给Shape的任何消息,Circle都能接收,那这么做完全是安全且合乎逻辑的。
15)单继承结构
单继承结构保证所有对象都属于同一个基本类型,可以在每个对象上执行某些基本操作。所有的对象可以很容易的在堆上创建。
单继承结构使得垃圾回收器的实现变得容易很多,而垃圾回收器正是Java对于C++的重要改进之一。由于所有对象都保证具有其类型信息,因此不会因为无法确定对象的类型而陷入僵局。
16)对象生命周期
垃圾回收器 “知道” 对象何时不再被使用,并自动释放对象所占用的内存。这一点同所有对象都是继承自单根基类Object以及只能以一种方式创建对象(在堆上创建)这两个特性结合起来,使得用Java编程较用C++编程要简单的多。
17)异常处理:处理错误
大多数错误处理机制的主要问题在于,它们都依赖于程序员自身的警惕性,这种警惕性来源于一种共同的约定,而不是编程语言所强制的。如果程序员不够警惕,这些机制就很容易被忽视。
异常是一种对象,它从出错点被 “抛出” ,并被专门设计用来处理特定类型错误的响应的异常处理器 “捕获”。异常处理就像是与程序正常执行的路径是并行的、在错误发生时执行的另一条路径 。
异常处理不是面向对象的特征----尽管在面向对象语言中异常常被表示成为一个对象。异常处理在面向对象语言出现就已经存在了。
18)并发编程
同一时刻处理多个任务的思想。
有一个隐患:共享资源。如果多个并行任务都要访问同一项资源,那么就会出问题。例如:两个进程不能同时向一台打印机发送消息。为了解决这个问题,可以共享的资源(例如打印机),必须在使用期间被锁定。因此整个过程是:某个任务锁定某项资源,完成其任务,然后释放资源锁,使其他任务可以使用这项资源。