在csdn上看到了这么一个帖子,觉得非常好就转帖了过来,确实,面向对象只是一种编程思想,如果在编程时不管遇到什么样的问题都要往面向对象上靠就变成形式主义了,方法就变成了目的,呵呵!
    
/* 莫特探员 
*   title:   我的面向对象程序观   
*   description:   描述我对面向对象的一些理解,思想上并不成熟,文章随时都在更新,希望大家都来参与讨论   
*   copyright:   copyright   (c)   2001   
*   company:   matrixfox   
*   @author   莫特探员   
*   @version 持续更新中。   
*/   
    
      
1)面向对象概念的一些误解
    
“面向对象”是一个如今被人叫烂的词汇,就像去年人们都喜欢把自己的公司打上“.com”的标记一样。其实有多少人能真正理解这个词汇呢,很难说。我喜欢这样来比喻人们对“对象”一词的滥用。“对象”就好比人们经常说的“酷”和“爽”,很多人并不仔细考虑这两个词的差别,在很多情况下他们是通用的,“酷”和“爽”通常表达“心情不错”的意思,你可以在你玩的高兴的时候,大声的叫嚷“太酷了,太爽了”,这个时候两个词汇是通用的。但是你可以说“这个人很酷啊”,但是你不能说“这个人很爽啊”。人们对“对象”这个词汇的滥用就发生在这里,“面向对象”和“基于对象”就好比“酷”和“爽”,这是两个不同的概念,但是人们通常将这两个词汇混为一谈,一律用“面向对象”来表达。常见的错误可以在此列举一些:   
    
1)有个人兴高采烈的和你说“我不喜欢flash 4   的脚本语言,flash 5 版本的action script 采用了新的面向对象的“.”语法,写起来很舒服。我现在一直用 flash   5 来做东西。”(同样的话语也发生在   director   的   lingo   脚本语言中)   
    
2)visual basic 采用了面向对象的属性和方法,比起过去的basic语言有了很大的提高。   
    
3)javascript   是面向对象的。   
    
等等。   
    
通常听到类似的话,你都要认真审视说话之人,分析他说的话。可以肯定一点,他并非真正懂得什么是面向对象的思想。很多人没有区分“面向对象”和“基于对象”两个不同的概念。面向对象的三大特点(封装,继承,多态)却一不可,通常“基于对象”使用对象,但是无法利用现有的对象模板产生新的对象类型,继而产生新的对象,也就是说“基于对象”没有继承的特点,而“多态”是表示为父类类型的子类对象实例,没有了继承的概念也就无从谈论“多态”。现在的很多流行技术都是基于对象的,它们使用一些封装好的对象,调用对象的方法,设置对象的属性。但是它们无法让程序员派生新对象类型。他们只能使用现有对象的方法和属性。所以当你判断一个新的技术是否是面向对象的时候,通常可以使用后两个特性来加以判断。“面向对象”和“基于对象”都实现了“封装”的概念,但是面向对象实现了“继承和多态”,而“基于对象”没有实现这些,的确很饶口。   
    
    
2)java   比   c++   在贯彻面向对象的思想方面更加彻底。我最近上的学习班的老师对我说:“c++   是打着面向对象的幌子,干着过程编程的勾当”,这句话我非常的赞同,而且我一直以来也是这么认为的。但是仔细听他讲解后,我才发现,我是只是理解了这句话前两层的意思。但是还有一层意思我没有理解。你可能要问,“难道   c++   不是面向对象的吗?”。事实上   c++   是真正的面向对象编程语言。但是它也是过程编程语言。为什么怎么说呢,   c++   的产生不但考虑了面向对象的特性,而且也更多的考虑了对   c   语言的向后兼容,使得   c++   这种杂合语言表现出“过程”和“对象”编程的双重性。你通常既可以继续用   c++   编译器来编写传统的   c   程序,也可以使用   c   ++   的类库或者编写自己的类来作面向对象编程。这种“两面性”使得人们可以继续保留原有的   c   代码,同时也阻碍了面向对象思想的推广。   
    
    
举个简单的例子,94   年的时候,我开始学习   c++   ,当时是学习   turbo   c++   自己带的一个叫作   turbo   vision   的类库来做项目。我的同学也用   turbo   c++   ,但是他一点也没有学习过   c++   这个语言,他只是用   turbo   c++   编译器来重新编译他以前用   turbo   c 写的程序,然后他自豪的对我说:“瞧,我用   c++   做的东西”,好像意思是说“我用 c++   开发项目了”,在那个   c   比   pascal   高档,   pascal   比   foxbase   高档的年代里, c++   的标签绝对是个很"酷"的标志。我其实很清楚他的行为。这就是“c++   是打着面向对象的幌子,干着过程编程的勾当”的第一重意思,也就是说,   c++   编译器对   c   程序的兼容性造成了最底层的“过程勾当”。在国内有很长一段时间,人们都是在用   c++ 编译器做   c   编程。   我当时在想,比起我那个同学,我才是真正懂得面向对象的人。我学习了   c++   语言,我懂得封装,继承和多态,我学习了   turbo   vision   的类库,我派生了   turbo   vision   的类库并编写了自己的类,所以我是懂得面向对象的。从某种意义上说,我这么想是对的。但是从面向对象程序员的分类来说,我又不完全懂得面向对象的思想。从事面向对象编程的人按照分工来说,可以分为“类库的创建者”和“类库的使用者”,通常创建类库的人才是真正懂得面向对象思想的人,他们创建类库供给那些“客户程序员”来使用,他们从头开始制作类库,他们进行面向对象的分析,设计,实现的全过程。当学习完   c++   后,我的第一个感觉是,从头创建一个类库真是很麻烦的事情,通常用   c   过程编程很容易实现的功能,你必须按照类的思想来从新建立对象,但是一旦类库建立好后,使用类库和派生类,以及维护代码都是非常舒服的事情。使用类库的人并不都是具备了面向对象思想的人,通常知道如何继承和派生新对象就可以使用类库了,然而我们的思维并没有真正的转过来,使用类库只是在形式上是面向对 象,而实质上只是库函数的一种扩展。这就是我理解的“c++   是打着面向对象的幌子,干着过程编程的勾当”的第二重意思,实际上用c++   编程的人,大部分不自己创建类,而是使用类库,这样就造成了他们把类库作为一种高级的库函数库来理解,并没有真正理解面向对象的思想。   
    
    
c++   的面向对象的思想推广很慢,直到   mfc   ,owl   ,vcl   这样的类库出来以后,人们才渐渐的接受了一些面向对象的思想。为什么这条面向对象的道路那么难走?我的答案是“因为   c++   给了我们第二条道路去走过程编程”,当然原因是为了考虑兼容   c   语言, 然而正是由于有了第二条老路才使得使得我们不会再去考虑新的面向对象编程思维方式。   
    
    
直到出现了   java   ,才真正迎来了面向对象的曙光。java   真正是革命性的东西吗?不是,所有现有的   java   的思想都是继承自其他的语言和技术,没有什么革命的地方,虚拟机的概念早在   20   年前的   ucsd   pascal   中就采用了,只是当时的机器速度太慢,虚   
拟机仿真造成的性能降低对于当时的硬件来说是相当严重的。java   本身的很多东西也借鉴了   c++   语言,连它的创始人也说,java   是   "c++--"   也就是说   java   去除了   c++的一些不太好的地方。所以说   java   本质上没有什么革命的东西,所以那些对   java 的赞美之词都是   sun   公司的宣传伎俩。没有一种语言会长久的存在下去,你很难说你的孩子在二十年后还会继续使用   c++   或   java,所以我们要抛开这些浮华词汇的背后,找寻真正我们需要学习的东西。否则今天我们大家都是微软的傀儡,明天   sun   公司起来了,我们就都是   sun   的傀儡。仔细研究美国电脑技术发展的历史,美国人一向喜欢象第三世界兜售他们的过时技术,而他们始终可以自豪的说,我们将永远领先你们第三世界国家二十年。我们始终在跟在美国人的后面学习他们的东西,这的确让人担忧。我说着说着又跑题了。java   虽然没有什么真正的革命性的东西,但是   java   在真正推动面向对象编程思想方面是功不可末的。使用   java   编程,你无需考虑到向后兼容什么语言的问题,它是重新建立的语言,你在掌握这门语言之前,你必须将自己的编程思想由过程编程彻底转向面向对象编程,因为   每个 java   程序,本身就是一个类,你编写任何java   程序,你都不自觉的在构造一个对象模板,没有第二条道路,只能是面向对象编程。(   我非常喜欢   java   将所有类定义和类声明放在一个文件中,而不是象   c++   那样,cpp   和   .h   文件是分开的。通常刚刚开始学习 java   的人不习惯,不过学习一段时 间,你就会体会到它的好处了。),   使用   java   编写程序(我更喜欢说---编写类,而不是程序)的时候,你会必须从一个对象的角度来考虑问题,因为你的程序就是一个类,你必须考虑把哪些东西作为成员变量,哪些作为方法,要生成几个类,哪些变量是成员变量,哪些是静态的变量和方法,等等。通常做完一个项目,你就已经将面向对象的思想运用其中了。之所以说java 在面向对象的贯彻方面要比   c++   彻底,就是因为你只能使用面向对象的方式来编写   java   程序,而   c++   却可以采用另外一条非面向对象的方式来编写程序。java   并没有什么真正革命性的东西,它最大的贡献当然是推广面向对象的思想了。   
    
java   总的来说是降低了继续过程编程的可能性,但是并没有完全消除它。面向对象是 一种思想,是我们考虑事情的方法,通常表现为为我们是将问题的解决按照过程方式来 解决呢,还是将问题抽象为一个对象来解决它。很多情况下,我们会不知不觉的按照过程方式来解决它,因为我们通常习惯于考虑解决问题的方法,而不是考虑将要解决问题抽象为对象去解决它。很多新的技术使我们更加趋向于过程而非对象的思想。最明显的就是   rad   (快速应用程序开发)可视技术的出现,人们可以通过设置属性和编写事件函数来快速开发应用程序,编写事件函数就是典型的按照过程编程的思想(至少我是这么认为的),试问有多少人能区分vb   和   delphi   ,c++   builder   ,java   的事件函数编写有什么本质的区别,   后三者都采用了   delegation   (委托模型),在   java   中是通过 anonymous   类(无名类),或者   adapter   类来实现delegation,这是一种面向对象的 构想,但是   vb   不是,所以这底层的区别都被上层的相似性所抹杀了,使用   jbuilder 编程的时候,我们如果没有仔细研究   java   的   awt.event   编程方式的话,通常也是把它当作普普通通的“类   vb"的编写方式来写程序,而实际分析它在后台所生成的代码,你才能明白这些代码是真正的面向对象的,但是如果你只是简单的把它当作可视编程工   
具,你是永远不会明白什么是”委托模型“,什么是面向对象编程的。这是我理解的“c++   是打着面向对象的幌子,干着过程编程的勾当”第三重意思。无论是   c++   还是 java   都有可能走过程编程的老路,   java   降低的过程编写的可能性,但是如果你没有   
具备面向对象的编程思想,你还是可能走面向过程的老路的。   
   
29 楼bbdragon(云梯)回复于 2002-01-22 11:59:04 得分 10
面向对象其实是一种方法学而已。文章有许多地方值得探讨。   
1。过多纠缠于oop,没理解面向对象的方法学,如果你用面向对象的方法分析,设计,采用基于对象的语言实现,或者过程化语言实现,难道不叫面向对象的程序设计开发?其实面向对象的语言只是让实现同设计更自然一点,一致一点。(当然选用面向对象的语言能获得更多特性)   
2。“一般类库的设计者才真正懂面向对象,使用者只是形式上的把类库当成函数库”其实类库只是面向对象在程序设计领域中的应用,而且大多类库由于历史原因只是用Wrapper   Facade 封装了API罢了。然而好多应用软件采用面向对象的分析设计实现。所以说,方法学同你用来作什么是没有联系的,什么场合适用什么方法学那你就采用就行了,别太勉强。   
3“编写事件函数就是典型的按照过程编程的思想(至少我是这么认为的)”?面向对象的方法学从不排斥过程。对象间通过消息交互就是过程。过程作为时间先后,因果先后而必然存在,普遍存在。别把面向过程的分析,设计,结构化语言等等同“过程”搞混淆了。事件函数是面向对象的消息处理。  
34 楼tvb()回复于 2002-01-24 15:33:28 得分 5
大家去看一下那些大型工程的源代码   
有好多都是用C写的,但是从里面你可以看到面向对象的影子。   
    
面向对象的思想并不是在面向对象的的语言之后才产生的   
而是先有了这种思想(并且已经用到了实际的编码之中),后来才   
出现面向对象的语言,才出现更加完善的面向对象的方法。
52 楼xiao_zhu(我真的很傻)回复于 2002-01-27 12:50:16 得分 5
作者在文中提到了面向对象和基于对象的概念。认为面向对象的语言和系统必须支持继承,而且必须支持继承才能支持多态,所以VB等不是面向对象的。   
    
我不同意这个观点,实际上继承分为实现继承和接口继承,作者提到的实际上是实现继承,   
但是继承还有接口继承,象COM并不支持实现继承,但COM支持接口继承。   
比如你可以定义一个交通工具接口,规定了交通工具应具有的一组行为,比如move等,然后你可以定义汽车,火车,轮船,飞机等交通工具,它们都实现了交通工具接口。   
现在假设你有一个复杂的交通管理系统,当你的系统收到某个消息时,你想让你管理的当前交通工具移动,你完全可以不用管当前交通工具的具体类型,是汽车还是火车或是飞机,而在你的系统中维护一个交通工具的引用,然后直接调用交通工具.move就可以了,系统会根据你当前交通工具的类型,作出相应的move行为,比如火车在铁路上move,飞机在天空中move等,这不是多态是什么?   
而且火车,汽车,飞机,轮船等都实现了交通工具接口,具有交通工具应具有的行为,这实际就是一种is_a关系,不是继承是什么?   
而VB作为完全基于COM的一种开发环境,是完全支持接口继承和多态的,难道不是面向对象的吗?
56 楼sqhua(拉长弓兮射天狼)回复于 2002-02-16 13:44:52 得分 0 
面向对象是一种思想,与语言无关。   
    
首先,在一个文件中写完C++的类声明和实现,这在文本模式下的编程完全不可取。   
    
当你用   Makefile   来组织编译时,就会有问题了,如果用上一堆   #define   
    
#ifdef,#ifndef   ,就比较乱了。   
    
刀是你的,怎么用,用来干什么都不关刀的事。没理由说这是一把好刀,   
    
这是一把聪明的刀,这是一把面向对象的刀。   
    
就象:兵者,诡道也。没人会说一定要用坦克才算是好的军事家。用什么   
    
武器都可能有“诡道”的效果。   
    
用汇编写的程序也可以体现出面向对象的思想。当然,用C++更简单一些,因   
    
为不少面向对象的东西得到了自然的支持。   
    
就象快速反应部队,以前可以是骑兵,现在能用空降兵就比较好。   
    
还是那句话:面向对象是一种思想。
 
                    
                     
                    
                 
                    
                 
         
