首页 > 代码库 > 面向对象编程思想的哲学起源(转载)
面向对象编程思想的哲学起源(转载)
http://www.xuebuyuan.com/566309.html
本来想象着写一整篇「面向对象编程思想的哲学起源」这样的题目,笔走纸上,方才发现这样的题目足够出本书,知识不够,写不动。但心里还是想写点自己的所思所想。
全篇就拿JAVA来举例了。众所周知,面向对象的四大基本要素:抽象(Abstract)、封装(Encapsulation)、继承(Inheritance)、多态(Polymorphism)。
很多人坚持《逻辑学》是唯物哲学的基础,不懂,姑且不论。哲学就是对自然学科的抽象,看柏拉图,更感觉哲学是在关心自然与人类的一种思辨;逻辑是一种工具,可直接参与到现实,指导人们的生产生活。关于逻辑的详细,可以去读一读殷海光(〈殷海光哲学与文化思想论集〉南大出版社,推荐一下)。按照我的理解,哲学就是把人类的各种经验总结起来,经高度提炼与缜密辩证之后,写成定义之类的文字,编纂成典,供查看,可使后来的人少走些弯路。
不知道说亚里士多德是逻辑学的开山鼻祖正确与否,古希腊的智慧真是百花齐放。废话少说,先看看一些定义——手上的书是三联书店在1951年出版的,维诺格拉多夫,库兹明合著,刘执之译,满篇繁体——
「人类对自然和社会的认识是从物质世界的对象对感官直接作用的结果所发生的感觉(Sensation)开始的。感觉是我们的意识对物质对象的这种或那种性质例如硬度、颜色等的反映。」
感觉很重要,是我们认识事物的第一步。人类可以发展「第六感」,可见,人类认识世界的潜力有多大。我们的感觉,是来自对「对象」的反应。对象很重要,我们从世界的千万对象中,通过比较,认识总结了事物,并分成类别,打个比方,生物学上的门纲目科属种,就是对自然界生物(对象)经过长期的认识总结之后,逐渐对它们产生了认识,这个认识的层次,就是抽象的层次,就对应产生了不同层次的概念,最终出现了上面的分类,越上层,抽象层次越高,概括越强,概念的内涵越广,在面向对象的设计中,就体现为接口。
门纲目科属种,是分类出来的,是概念的范畴,随着人们对客观世界生物认识,从种的概念一直抽象到门的概念,门便是此类概念的最高抽象,「门」便可以对应于OOP中的接口。类和概念,某种程度上是同义词。
Bruce Eckel在其经典著作 Thinking in Java中讲:Everything is an object(万事万物皆对象)。大家将此话视为「毛主席语录」,久诵成典。在逻辑学中早有此解释:「我们周围现实环境中的事物和现象,在逻辑中叫做对象(Object)」。现在,我们可以大致从逻辑学中看出面向对象思想的哲学脉络了。Bruce把哲学的语言文学化,兼具感染力。
对象之所以有意义,是因为可以被感觉,因为它的「存在」。一个物体占有空间和时间,才能在宇宙中确立它的坐标,表示它的存在。这个不消多说。在计算机世界,各种软件硬件环境组成了一个虚拟世界。一个程序,只以概念(类的源码)形式存储在硬盘上,有什么意义呢?我们要让这个程序运行起来,执行他的工作,才算是赋于它以意义,写这段代码的人,也算是血汗没白流。所以,我们要让这些源码中的类(概念),对象化,让其存在,运行,才有其意义。我们常用new关键字来对象化一个类,对象化,就是初始其占有空间,当其某个方法被调用时,产生了「行为」,占用了CPU的时间,很好,占有内存空间和CPU时间,确立了它在内存中的坐标,表示它存在,自此始,它有了意义。
同理,若一个对象在内存中失去了意义,便可以调用析构(destructor)方法(注:JAVA中的垃圾收集机制,可以自动回收无意义的对象),释放空间与时间的占用,让给其它的有意义的对象。人类亦是如此,每个活人皆是对象,死掉了,要注销户口,释放其占用的空间与时间,让给八零后的新一辈。 我这样理解,概念就是对客观世界中具体对象(Objects)的抽象,概念也是一组数据而已,概念可用数字来表达,概念阐述了地球上的人类对其周遭世界的看法,概念就是归纳,概念就是类(OOP中的概念,类class更准确理解为类型type),概念可以回归世界的对象中,概念是人们在逻辑上认识事物的第一步,是最小「单位」。书中这样定义:
「概念就是反映对象之一般的和本质的属性的思考(对象的本质属性就是表现对象的根本性质的那种属性)。」
亚里士多德最早阐述了类的概念,例如「鸟类」、「鱼类」。看到一群鸟,就有了感觉去比较,区分,最终认识他们。比较非常重要——
「事物首先是靠比较法来认识的。」
所以在JAVA的宇宙类Object(对象,物质的意思)类中,有equals的方法。所有的类都要继承Object类,equals的意思,就是用来实现程序中两个对象的比较。顺便再阐述一下比较(Comparison)的定义:
「这是用以确定客观世界的对象、现象的类似之点和差异之点的一种逻辑方法。」
简单地说,概念是怎么得到的呢?通过抽象。
「抽象(Abstraction)——这是我们用以思维地分出对象,现象的本质性质,而抽去对象和现象的非本质的,副次的性质的一种逻辑方法。」
和概念的定义大体上一个意思。在任何一个思考过程中,不使用抽象,是不可能的。当我们写程序的时候,写一个「飞机」的类(也就是写一个「飞机」的概念出来,只不过概念的书写语言不是英语或汉语,是一门程序语言如C或JAVA罢了),首先就要「抽象」了,看我们面向对象的四大特点之第一,便是这个抽象。
当我们写一个「飞机」的类,我们就会去观察尽可能多的飞机(对象),因为观察的数量与程度,与对飞机这个概念的认识深度有直接关系,对后来的总结抽象,至最终的概念,都将起重大作用。像我们只观察了飞机的外表,若观察过内在的机理(如发动机),这个概念可能就要有些变化。我们研究抽象出了第一步——飞机有机翼、机身、起落架等等,随着观察数量的增多和观察程度的深入,我们又对飞机的抽象加深一步,增加了发动机、驾驶舱等属性。
概念与语词,需要说一下,我们对概念的语词,像上面我们定义「飞机」的概念,飞机就是语词。概念的语词,多为名词,思维自然而然会做好这些事情。属性也皆为名词,方法是动词。一个类中,属性的作用就是存储数据,方法(或函数)的作用便是操作这些数据,退一步讲,就是动词对名词的修饰。类名作主语,名词谓语,组成一个完整的语句,同时也是一个完整的概念。以动词为名的方法的意义,是当概念回归时,具体对象所表达的行为模式。如我们抽象了飞机的概念,我们可凭此概念去判别客观世界中的某一物体是否为飞机,但是飞机本身客观存在的意义又是这个具体对象的意义——它可以运输货物,或执行战斗任务。起飞时收起起落架,降落时打开起落架,其中「收起」、「打开」便是一种行为,是这个「飞机」类的方法。方法是动词命名,代表一种行为,修饰限制其属性,属性为名词,构成动宾结构。
言归正传,对于属性,如果大家对面向对象的编程略微熟悉,便知它的意义了。
「对象的品质和特性在逻辑上叫做属性。」
上面我们在「飞机」的抽象中,列举了诸如机翼、起落架,发动机等属性,这都毫无疑问的是飞机的「品质和特性」了。
看来面向对象的编程思维确实有清晰的哲学源头的。我们在写「飞机」这个类时,写了上述的属性,然后非常自然的封装起来。就是我们在定义属性时写的private(私有的)、public(公有的)、protected(受保护的)等修饰符(modifier),这些修饰符,只是为了限定类的属性的开放程度。例如private的属性,在继承的类(概念)中是不能够被直接使用的,这个封装的哲学,与逻辑学本身不好说有直接关系。但是却有着来自对生物学的深刻模仿。
继承,是模仿了生物学上的继承。后代继承父辈基因,具有父辈的某些生物学特征。例如,我们抽象了飞机出来,飞机的祖宗是莱特兄弟的那一架,后来生产出来的,就是对莱特兄弟的飞机的概念的不断丰富。假设我们写了一个莱特兄弟的「飞机」类(概念),后来我们目睹了飞机的发展,我们就要不断的写新的类,继承自这最初的「飞机」。这些继承的类(概念)出现了更多的特点和品质,所以,我们要加。例如出现了喷气式飞机,就要增加涡轮发动机,出现了隐形战斗机,我们要加涂装材料这个属性,出现了水上飞机,就要继承或添加一些关于船的属性——杂交也是可以的,像骡子。
当我们在父类(父亲)的属性上用了private的修饰符,就是说,这个属性,是个隐性基因,隐性遗传到下一代。下一代不能直接表现出来这些属性(品质、特点),当然也不能使用。虽然如此,这些基因(属性)到底还是被继承了。只要不实行如此严格「封装」,子类(儿子)便拥有从父类(父亲)继承来的一切特点,父亲能做什么,儿子也同样可以(没有基因突变一说,毕竟CPU要严格行事,否则,真成了智能计算机了,人类到这一步,恐怕还有一段路要走)。
父亲有十个儿子,十个儿子各自继承了父亲的品质(类的属性)和行为(类的方法),又各自有自己的特点,例如,都有胳膊腿儿,父亲会用它们来耕作劳动,儿子们可能各异禀赋,或棍棒武术,或翻书写字,或雕刻打磨,或裁补设计——总会产生新的特点,就需要在方法中重新来写这个逻辑(行为逻辑),于是,在定义了新的行为之后,区别于父亲。当父亲命令儿子们:都给老子去活动活动手脚——便有的裁剪衣饰去了,有的舞枪弄棒去了,有的则摇头晃脑之乎者也去了。这就是多态(Polymorphism),就是一个属性本来所表现的状态,由于继承,由于概念被丰富了,产生了不同的行为状态。多态是由于继承的发生,继承本身,就是对概念的丰富和完善——新的飞机出来了,有了新的属性和功能,那么旧的飞机类型派生出来新的飞机类型,来解释当下飞机的新的概念。多态是继承的结果,是一个进化的过程。因为,世界总不能够千篇一律。靠近海滩的蚂蚁,生出翅膀来,对生物存亡有重大意义,这个蚂蚁的概念,就要拓展。
于是整个面向对象四大要素的哲学脉络,便可触可摸了。实用哲学,有其现实意义,作为一种科学的工具,当仔细研究。至于其它,看不懂;看懂的,十之八九不是疯子,就是真正的哲学家。只总结最近的一些思考,杂乱,不堪再写,到此为止。
二○○九年五月十四日
面向对象编程思想的哲学起源(转载)