文中笔记均为个人观点,如有错误请大家不吝指出,谢谢!
原书为《java编程思想 第四版 中文版》
第一章 对象导论
“我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来······除非赞成这个协定中规定的有关语言信息的组织和分类,否则我们根本无法交谈。”
——Benjamin Lee Whorf (1897 ~ 1741)
计算机革命起源于机器,因此,编程语言的产生也始于对机器的模仿。
但是,计算机并非只是机器那么简单。计算机是头脑延伸的工具(就像Steve Jobs常喜欢说的“头脑的自行车”一样),同样还是一种不同类型的表达媒体。因此,这种工具看起来已经越来越不像机器,而更像我们头脑的一部分,以及一种如写作、绘画、雕刻、动画、电影等一样的表达形式。面向对象程序设计(Object-oriented Programming,OOP)便是这种以计算机作为表达媒体的大趋势中的组成部分。
本章将向读者介绍包括开发方法概述在内的OOP的基本概念。本章,乃至本书中,都假设读者已经具备了某些编程经验(当然不一定是C)。如果读者认为在阅读本书之前还需要在程序设计方面多做些准备,那么就应该去研读可以从www.MindView.net网站上下载的《C编程思想》(ThinKing in C)的多媒体资料。
本章介绍的是背景性的和补充性的材料。许多人在没有了解面向对象程序设计的全貌之前,感觉无法轻松自在地从事此类编程。因此,此处将引入许多概念,以帮助读者扎实地了解OOP。然而,还有些人可能在看到具体结构之前,无法了解面向对象程序设计全貌,这些人如果没有代码在手,就会陷于困境并最终迷失方向。如果你属于后者这个群体,并且渴望尽快获取Java语言的细节,那么可以先越过本章——在此处越过本章并不会妨碍你编写程序和学习语言。但是,你最终还是要回到本章来补充所学知识,这样才能够了解到对象的重要性,以及怎样适用对象进行设计。
笔记:个人认为,对语言有操作基础以后,在阅读这本书收益会更大。当然,也可以多读几遍。
1.1 抽象过程
所有编程语言都提供抽象机制。可以认为,人们能够解决的问题的复杂性直接取决于抽象的类型和质量。
笔记:这句很精辟“人们能够解决的问题的复杂性直接取决于抽象的类型和质量。”
所谓的“类型”是指“所抽象的是什么?”汇编语言是对底层机器的轻微抽象。接着出现的许多所谓“命令式”语言(如FORTRAN、BASIC、C等)都是对汇编语言的抽象。这些语言在汇编语言基础上有了大幅的改进,但是他们所做的主要抽象仍要求在解决问题时要基于计算机的结构,而不是基于所要解决的问题的结构来考虑。程序员必须建立起在机器模型(位于“解空间”内,这是你对问题建模的地方,例如计算机)和实际待解决问题的模型(位于“问题空间”内,这是问题存在的地方,例如一项业务)之间的关联。建立这种映射是费力的,而且这不属于编程语言所固有的功能,这使得程序难以编写,并且维护代价高昂,同时也产生了作为副产物的整个“编程方法”行业。
另一种对计算机建模的方式就是只针对待解问题建模。早期的编程语言,如LISP和APL,都选择考虑世界的某些特定视图(分别对应于“所有问题最终都是列表”或者“所有问题都是算法形式的”)。PROLOG则将所有问题都转换成决策链。此外还产生了基于约束条件编程的语言和专门通过对推行符号操作来实现编程的语言(后者被证明限制性过强)。这些方式对于他们所要解决的特定类型的问题都是不错的解决方案,但是一旦超出其特定领域,它们就力不从心了。
面向对象方式通过向程序员提供表示问题空间中的元素的工具而更进了一步。这种表示方式非常通用,使得程序员不会受限于任何特定类型的问题。我们将问题空间中的元素及其在解空间中的表示称为“对象”。(你还需要一些无法类比为问题空间元素的对象。)这种思想的实质是:程序可以通过添加新类型的对象是自身适用于某个特定问题。因此,当你在阅读描述解决方案的代码的同时,也是在阅读问题的表述。相比以前我们所使用的语言1,这是一种更灵活和更强有力的语言抽象。所以,OOP允许根据问题来描述问题,而不是根据运行解决方案的计算机来描述问题。但是他仍然与计算机有联系:每个对象看起来都有点像一台微型计算机——它具有状态,还具有操作,用户可以要求对象执行这些操作。如果要对现实世界中的对象做类比,那么说它们都具有特性和行为似乎不错。
Alan Kay曾经总结了第一个成功的面向对象语言、同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这些特性表现了一种纯粹的面向对象程序设计方式:
1)万物皆为对象。 将对象视为奇特的变量,它可以储存数据,除此之外,你还可以要求它在自身上执行操作。理论上讲,你可以抽取待求解问题的任何概念化构件(狗、建筑物、服务等),将其表示为程序中的对象。
2)程序是对象的集合,它们通过发送消息来告知彼此所要做的。 要想请求一个对象,就必须对该对象发送一条消息。更具体地说,可以把消息想象为对某个特定对象的方法的调用请求。
3)每个对象都有自己的由其他对象所构成的存储。 换句话说,可以通过创建包含现有对象的包的方式来创建新类型的对象。因此,可以再程序中构建复杂的体系,同时将其复杂性隐藏在对象的简单性背后。
4)每个对象都拥有其类型。 按照通常的说法,“每个对象都是某个类(class)的一个实例(instance)”,这里“类”就是“类型”的同义词。每个类最重要的区别于其他类的特性就是“可以发送什么样的消息给它”。
5)某一特定类型的所有对象都可以接收同样的消息。 这是一句意味深长的表述,你在稍后便会看到。因为“圆形”类型的对象同时也是“几何形”类型的对象,所以一个“圆形”对象必定能够接受发送给“几何形”对象的消息。这意味着可以编写与“几何形” 交互并自动处理所有与几何形性质相关的事物的代码。这种可替代性(substitutability)是OOP中最强有力的概念之一。
Booch对对象提出了一个更加间接的描述:对象具有状态、行为和标识。这意味着每一个对象都可以拥有内部数据(它们给出了该对象的状态)和方法(它们产生的行为),并且没一个对象都可以唯一地与其他对象区分开来,具体说来,就是每一个对象在内存中都有一个唯一的地址2。
笔记:一切皆对象,面向对象编程,从对象的角度出发思考问题。解决一个问题应该想,有哪些对象、对象做什么,对象怎么做。(个人观点)
文中会出现,如错字、语句不通、理解偏差等问题,请及时联系或在下方评论指出。我也会尽量按照原书将内容呈献给大家,谢谢!