新手为什么总抱怨面向对象编程(以下简称OOP)难学?
新手为什么总无法深刻的理解OOP的思想?
能写出一个合格的类就代表你理解了OOP的思想了吗?
什么样才算真正的理解了OOP?
OOP难在什么地方? 为什么我总是学不会?

相信很多人和我一样,在学习OOP的时候总会有上面那么多的问题..不过不要紧,我们今天就来探讨一下这些问题。

我个人认为..很多人都认为会写一个类就理解了OOP的思想了…这个思路是错误的..这就是为什么很多人虽然会写类了..但是写出来的类很“畸形”..究其根源..还是因为没有深刻的理解OOP的思维.

我建议大家..努力学习OOP基础..先不要去尝试写一个值得骄傲的类..你扪心自问..你虽然可以写出一个优秀的类.但是你理解了OOP了吗??

现在对于广大的PHPer来说..一个非常困难就在眼前..不光是我们这些菜鸟..就连一些著名的开源程序也一样..对于OOP非常不明确..

根据我的理解.我觉得大部分人写出”畸形”的类还是对OOP没有理解的非常深刻..那么好..今天我们大家就来探讨一些这个问题…

我们首先得知道.这个世界为什么会有OOP.为什么会出现OOP..一个事物从出现到发展.到今天的大红大紫..肯定有它无可替代的优越性..这种优越性经过这么多年的发展…很有必要普及到每个程序员..因为作为一名程序员.一定要有这样的思想..你的程序不是写给你自己的..你的程序是写给他人甚至后人看的..一段优美的代码也许一个程序员一生只能写出一段.但是这段代码也许会对以后发生惊人的意义..所以建议大家以后写代码.不要为了赶时间.不要为了着急实现某项功能..希望大家仔细锤炼代码..仔细思考..这对于你本人也是一种提高..

其次我们得理解为什么程序最初是面向过程的..也就是为什么会先有C而不是先有C++..好像这是个人类学的问题.或者说是一个哲学问题..人类思考问题是按照某一种过程的..这一个过程的结束也许可以发生一个质的改变..因为时间是这个空间不可缺少一个维度.所以他决定了事物都是按照一个过程发展进行的..所以从这个角度来说..面向对象于面向过程并不冲突的..其实面向对象是一种思维方式.而不是一种处理事务的过程..

为什么会出现面向对象呢??这个也得从人类的认知说起..因为人们逐渐发现了..这个世界是可以总结出来的..人们为了更好的判断事物.总是自觉或者不自觉的在给事物进行归类..这种归类的过程就是人们对面向对象的思维的一种认识.一种学习.一种进步..

人们会把水果放在一起储藏..再把肉类放在一起储藏..水果中又把容易变质的放在一起..这些不自觉的行为当被上升为理论的时候..这个强大的面相对象的就出现了..

一切皆对象.这句话果真不错..我目前还没有发现这个世界上不是”对象”的一种事物..你能找到吗??你理解这句话吗??噢对..貌似”时间”不是对象..那”时间”又是什么呢??这个需要跟霍金商量下吧..

我来具一些例子..我的Acer 4710就是笔记本的一个对象..笔记本这个笼统的概念又是从一体机发展而来的..而一体机又是根据我们平常所说的台式机发展而来的..

我们每个人都是人类的一个对象..太阳是恒星的对象..地球是行星的对象..等等等等..总之..我们每天都会接触无数的对象..每天都在不自觉中使用面向对象的思想..

那么好.一个最难解释的问题来了..你说一切皆对象没错..那么这跟我们写程序有什么关系呢??如何跟我们的程序发生联系呢??

其实是非常容易被解释的..你可以想象一下..我们程序员写的程序..一般来说.都是为了解决某个实际问题的..而这个实际问题就可以被牵扯到N多个对象..比如用户登陆..一个用户登陆他就是一个对象..

那么好.问题又来了..这个比起我们面向过程的编程方式有什么区别呢??我们为什么要使用面向对象的编程方式呢?

这个问题问的非常好..以致于一些书籍都没有解释..说到这里我BS一下市面上N多的OOP的书籍..大部分都是你抄我我抄你..没有一点创新..这些OOP书籍用了大部分篇幅讲了如何封装.如何多态.如何重载.如何继承.讲了类和接口等等等等..但是往往新手最迷茫的OOP的思维方式却很少提到..这里我再插一句..人云亦云总是可气的..现在很多OOP书籍费大力气讲如何封装.什么叫闭包等等的概念..学完到后来我才发现..OOP是开放的.是一种思维方式..封装并不是OOP必须的..人们大夸其辞得描述封装时OOP的三大特点之一.是不得不掌握的内容是非常重要非常重要的内容..我实在不敢恭维..依照我的理解..OOP是一种思维方式..封装是这个大思维方式下的一种扩展..当我们接触到了JavaScript的面相对象的特性后..当我们接触到面向切面的思维方式后..封装是不是又变得不是那么重要了呢??引用Exceed PHP论坛上面仁兄的一句话.

说到OO,每个人都会联想到类的封装,
所有教科书也是这么强调着写的。。。。。
很少有人关注类也是应该有开放性的。

好了.我们就不再为这个问题纠缠了..我们回到上面的问题上..为什么要选择OOP.

这个确实值得每个人去思考..而且这个问题到现在为止.没有一个准确的答案..有不少大牛也在争论这个问题..我们今天是为了学习OOP而探讨这个问题的.所以我们就抛开争论..
其实这个问题也非常好回答..为了提高代码的层次性.提高代码的重用性.减少代码的耦合性..这些很官调的话我们很难理解.为什么??很不幸.我的回答是.因为我们是PHPer..

这里我们举个例子..今天我特意去查询了下所有的UML工具..令人失望的是.这其中的大部分工具全部是for Java或者C++的.即使是有PHP的也是一种扩展的形式存在的..目前我还没有见到过一种专门for PHP的UML工具存在..扯开UML和语言有没有直接的关系不说(UML跟语言真的没关系吗??)..这个现象我们需要思考下.为什么PHP这么遭人唾弃..但是又为什么从google查询PHP的结果要比Java多N倍.为什么??

我想.这个原因大概就是我们所说PHP是一种”草根”语言..

我并没有半点鄙视PHPer的意思..因为我本人本身也是名PHPer..大部分的PHPer都是单干..正因为PHP的灵活.所以单干的比较多..而且效率很高..没几天就可以做出一个引以自豪的项目..很少是一个大型的团队..所以很多人根本没有体会到提高代码的层次性有什么好处..也更难体会到OOP的好处..这也就是为什么OOP在PHP中这么难被理解..也更难被运用到项目中了..

而Java就不同了.Java大多是大公司运用的项目.所以几十人的团队是经常的事情..
但是PHP真的就比Java更”草根”吗??

我想事实不是这样的..草根只有对于程序来而言的..PHP是自由的.是开放的.虽然他不严谨.但是他比较起Java更加灵活..比如Java要实现面向切面的编程..确实是不容易的..而PHP一个简单的runkit就可以搞定..而且我曾经看到一个人在寻求在Java中如何实现PHP的魔术方法..这是我们PHPer很引以为自豪的事情..所以不要再认为PHP是草根语言..PHP是足够强大到胜任今天的每一个Web项目的..只要你有优秀的策划..难道FaceBook不是一个很好的例子吗??

如果你一个人做一个项目你会怎么办??直接上来就敲代码吗??在一个项目中..策划要占很大的比例..策划的时候要对系统的各个部分的可行性进行分析报告..要对系统的各个功能进行建模..对于Web来说.此时基本可以设定这个项目要写哪几个类.哪个类都有什么样的功能等等.

比如我们要做一个用户注册登陆的简单的系统..那么首当其冲的是要有一个用户类..这个类其中最起码的方法有addUser(用户注册) login(用户登录)..所以在项目策划的时候.我们就可以写一个接口..把这些方法定义为抽象方法..这就好像你是个小BOSS.然后你对手下说.去.把addUser login这两个方法给我完成了..但是你手下并不总是那么听你话的..也许他们会偷懒忘掉一个.也许他们会写出来.但是方法名给你改了.比如改成了 setUser userLogin..这对于一个团队来说.是一个非常头疼的事情..你这个小BOSS很难规划..你说的话他们都不听.你这个BOSS是不是有点名不副其实??

还有另外一个好处..比如你离开这个公司了.但是你代码你是带不走了..所以以后的代码维护又要交给你的下一任了..这个人也许会选择修改你的代码..但是如果他足够聪明是不会这么做的..他会选择性的吸收你的代码.比如你的代码 addUser 正是他想要的.但是你写的login已经不符合他的要求..所以他需要的是什么?对了.只需简单的覆盖即可..这样做的好处是没有修改一点你的代码.这是因为指不定哪天你的代码又会被又到..这就是我们经常在SVN的段落注释中见到的那句话(如果到XX年XX月XX日这段代码还没有被用到.那么你就可以删除)..这是个保险的行为..

其实OOP就是这点东西.是不是觉得我说的跟书上的还是很一样?没什么收获?不要紧.我们继续来.

为了真正的理解OOP.还需要代码的帮助..下面是一段Java代码

int a=5;
int b=6;

如果你已经理解OOP.你应该很惊讶的看出来.这其实就是一段非常具有OOP特征的代码..为什么这么说呢?

每个人几乎都知道a和b都是int类型..那么好我来出一道填空题.

a和b都是int的(__).

这里的括号里你会选择填什么?当然有了上面的铺垫.我相信你会填”对象”的..

填什么不要紧.最主要的是理解它..int这是具有一类的虚拟概念.就像鸟类一样.没有一直鸟的学名叫做鸟..1,2,3,5,6,7,4,23等等都是int的一个对象.他们首先是属于int的..其次.他们又有了自己的特征..比如大小. 1比2小.2比0大..这样就产生了多态..多态其实很好理解..我们每个人就是人类多态的表现..如果没有多态那么这个世界就会很单调..没有这么丰富多彩了..而且2还可以和1有些瓜葛.比如2=1+1..所以我们可以说每个正整数都是继承自1这个数字..总之.这些体现了OOP美妙的思维..

再来看一段Java代码.

int test(int a);

这是一个没有方法体的方法..根据上面的理论.我们可以推断出.其实test这个方法也是int的一个对象..只不过他不是一个确定的数字.而是一个过程..经过这个过程可以计算出一个数字..反正最终还是一个数字..再看里面的参数..比如我传进去一个2..那么好我问你.这个2是以什么方式传进去..看.又是对象吧..

所以来说..其实对象的思想你一直在用.就是没被注意..以后你需要一段时间.可能很长..尽量用这种思想去思考问题..

面向对象是一种思维方式..是一种积极解决问题的途径..

这里就出现了现在大部分PHPer包括我在内的这样一群人..这些人都刻意的为了OOP而去OOP..

这些人自认为对OOP已经很了解..所以时常的去研究OOP如何编程.如何写出一个漂亮的类.如何对类进行漂亮的封装..如何对类进行继承..接口是怎么运用的等等..总在这些问题上纠缠..越纠缠越晕乎.越晕乎越对OOP不了解..至此就变成恶性循环了..

如果真正的理解OOP的思想后..你的思维方式也许就会发生一些改变..

也许以后的你..看问题将会更加全面..

我再次重申: 面向对象是一种思维方式,它不仅对我们写程序大有好处..甚至对你处理现实中的问题上,对你的自身修养上都会有很大的提高。