程序员抽风极多
--献给OOP的初学者
1说明:
1,C++,Java,C#等所有面向对象语言都适用本文。
2,请打开大脑的思考功能,否则以下内容不用看了。
3,注释以//开头,内容一般用斜体。
4,关键字用黑体标出。一般都是专业术语。
2作者简介
姓名:王涛(未婚)
Email: taoge007@sina.com
CSDN: taoge1984
3声明:1版权是我的;2可被任意转载;3转载时不可删除本文以上内容。//我对你没有任何约束力的,所以你不照做,我也没有任何办
//法。你我都期待更多的网络好文章出现,那么我们应该尊重
//作者(including me)。谢谢阅读!Thank you very much!
4免责声明:虽经多次校订,但是BUG仍有存在的可能性。如果你能告诉我BUG所在:if(girl)送飞吻;
else 送祝福;
5内容概要:介绍OOP的四大核心--抽象封装继承多态,扫清初学者所有概念上障碍。
6最重要补充:我这玩意只能让你学的很轻松,但是你若想成为高级高薪程序员,请记住:高手是自己练成的!上机上机再上机!
第0章 程序一生
不详细解释一下内容://上机n次就明白123;工作后就明白456.
1分析,2设计,3编码,4测试,5交付,6维护。
从3起步,向2努力,向1学习;从1起步,向5努力更牛X。
这是一个软件按照顺序经过的6个阶段。顺序绝对不可能颠倒。 分析,设计,编码是所有编程必不可少的。测试,交付,维护在商业软件中也必不可少。如果你自己练习的话,分析设计编码就够了。哪怕简单的题目也不应省略了设计这步。
一个误解:调试就是测试。调试和测试两码事。调试是编码的最后一步,调试不过关,没有编码程序员胆敢交给测试程序员测试。
这六步是有不同的团队完成的。//小练习自己搞定,你雇不起人。
1分析难度最大,薪水最多,买房买车,结婚不愁。
2设计难度略小,薪水略少,破车破房,婚嫁不难。
3编程最简单, 车难搞,房难搞,老婆更难搞。
4测试稍难, 比编程累,比编程提升快,和编程差不多。
5交付,老板的活。
6维护,售后服务,适合不上进混日子一族,也可能是123来兼职。
记住这句话:根据客户的要求做分析,根据分析的结果做设计,根据设计的结果做编码;
测试当然是测试编码的结果了!就是测试编好的程序。交付必然是交付测试无误的程序(没测出的BUG有存在的可能)。维护必然是维护交付出去的软件。
第一章 四大家族前传
之
打蛇打七寸
面向对象编程,英文简称OOP,是当今毫无疑问的主流。泛型编程和面向构件编程也是以OOP为基础的。所以,不管是想在软件行业混还是想以后做程序员牛人,OOP都是必须要拿下的!
《投名状》中,李连杰说的一句话,让我重新领略了这句话的内涵:“打蛇打七寸,擒贼先擒王!”。蛇的心脏与头部的距离大约是七寸左右,也就是一个手掌的长度(一米多的蛇大约是这样,蟒蛇等大家伙除外),所以这个心脏所在位置被石头砸一下,蛇即刻丧命。以我N次与蛇狭路相逢并大获全胜的经验来看,这句话经历了实践检验的。//不是吹牛,是真的。小时候在山东山区长大的,仍清晰地记//得三次用石头砸蛇的情景。这是城里土鳖无法想象的。我相信童年//在山东山区的土鳖都有砸蛇的经历。土鳖在这里泛指不了解外部世
//界的人,不带有任何贬义。我也是土鳖,中国的土鳖。期待能成为
//地球的土鳖,至于太阳系的土鳖就不奢望了。
那么请思考:
OOP的“七寸”在什么地方?
也就是OOP的要害在那哪些地方?
也就是OOP最为核心的东西是什么?
也就是OOP的核心框架是哪些部分组成的?
if(你没有思考) go out ;//再往下看就浪费你时间了,所以不要看了。
else go on ;//看看和你思考的是否一样。
掌握了这些框架,也就掌握了OOP的灵魂;以下内容将给出答案。
答案是:抽象,封装,继承,多态。//请尽量忘记这8个字!是忘记,
//不是记住。不需要记忆。你仅仅需要知道存在这些词汇就可以,因//为下面我会说出不可能忘记这8个字的方法。如果你一直在思考本//文怪异的名字,如果你足够机灵,那么也许你已经有答案了。
抽风极多,意思是某个地方抽风的人不是一般多,是极多。这是很容易记住的。但是 “抽象 封装 继承 多态 ”却是不容易记住的。如果把这8个字的第一个字拿出来,即“抽 封 继 多”,那么我们也是很容易地联想到“抽象 封装 继承 多态 ”。如果把“抽 封 继 多”进一步变换为“抽风极多”,我们也是可以很容易地从“抽风极多”想到“抽 封 继 多”,进而想到“抽象 封装 继承 多态 ”。前面已经说过:“抽风极多”是很容易记住的。问题到这里就解决了。
第一章附加章 最牛数学思想
即
化归思想
请思考一下:我们用了什么样的思想解决了记忆这8个字的问题?变换的思想。什么是变换呢?
变换的目的是:化困难为简单。
变换的步骤是三步:变换,解决,反变换。
1变换:就是把困难的问题化为另外一个问题而且是简单的问题;
//如把 记住“抽象 封装 继承 多态 ”变换为 记住“抽风极多”。
2解决:就是解决这个简单的问题。
//如把 记住“抽风极多”这个问题解决;真的很好解决。
3反变换:就是把已经解决了的简单的问题的结果变换为在困难
问题中的的存在形式。
//如由“抽风极多”想到“抽象 封装 继承 多态 ”。
在理工科中变换的思想是无处不在的!数学中有傅立叶变换,拉普拉斯变换,三角变换;专业点说就是化归思想,此乃数学中最重要的思想,它排第二,没有同类敢排第一。
第一章之超级大赠送:数组
计算机中有那些变换?十进制到二进制的变换,这是最典型的。编程中,这种思想也是大有用处的。如学习数组时,数组元素的排序当然是第一个,第二个,第三个,等等。古今中外,对事物的排序都是从第一个开始的,这是符合人的习惯的!我也说了这是人的习惯,但这是计算机的习惯吗?如果你了解一点计算机的知识,那么你应该知道计算机是用二进制的。二进制就有 0 和 1这两个数字。显然,0比1大。
排序的潜规则是什么:当然是从小到大开始了。据说姚明上学时,在列队中,总是自觉地站到最后一个位置。姚明站到队伍的第一个位置是很滑稽的,当然,奥运会开幕式做旗手是两码事,因为他不在队伍中;后来闭幕式中姚明和叶莉不也是自觉地站到队伍后面了吗。。
计算机是人发明的产物,必然执行的是人的意志,所以计算机也是遵守这个排序的潜规则的。所以计算机排第一的是0,排第二的是1。这就意味着计算机中排序和计数都是从0开始的。计算机说第0个,那么对我们来说就是第一个!这个变换,你是必须要掌握的。当你被计算机同化的时候,也就是你习惯计数和排序从0开始的时候,那么你不需要悲哀,尽管你已经比常人略显疯癫了,因为这表示你已经是一个程序员了。
数组是属于程序设计语言的概念,当然也是建立在计算机硬件条件之上的,那么就不难理解数组元素的计数是从0开始的了。这是很不符合人的习惯的!!这个矛盾如何解决?变换来解决。在算法阶段,这是人的天下,自然是第一个,第二个。当把这个算法变成设计,进而根据这个设计来编程时,就进入了计算机的世界。变换的方法是把序号减1,就得到了在数组元素下标。反变换自然就是把数组元素的下标加1得到序号了。
数组元素的下标,表示数组元素的分布位置。我们关心的是第几个,也就是序号,所以序号是属于面向人的概念,不是数组拥有的概念。数组是没有序号的概念的,数组有的仅仅是下标的概念。数组元素的下标从0开始是有很多好处的,等学到指针,数据结构,数据库时,都会体会到这种好处,而且是不一样的感觉。说句题外话,很多教课书是不区分下标和序号的概念的,这是很糟糕的事情。会给初学者造成极大的障碍。两者一混淆,书就成天书了。如果能区分,书真的很简单。扯的有点远了,尽管没有出程序设计的范畴,下面继续聊聊“抽风极多”。
//精彩内容coming,请自觉休息5分钟后在继续阅读。
第二章 少林寺=抽象TheKingOfWorld
请思考:题目为什么用少林寺?
天下武功出少林,我用到的是这句话包含的意思。天下武功皆以少林为根基,天下武功都是建立在少林寺武功的基础上的。姑且不论这个说法的真伪性,这里姑且认为是真的。//俺也是习武之人,且认//为这句话在一定程度上是对的;就是说不是无条件的为真。元朝时,//禁武令横空出世,练武就有了造反的身体和技术,所以元朝才会这//么做。但是蒙古人是信奉喇嘛教的,喇嘛教和佛教是一个祖宗的,//都是印度过来的。少林寺是佛教的地盘。再加上当时少林寺方丈超//级会做人,和蒙古大汗扯上了关系。结果是大宋被灭,但少林寺不//仅完存,而且还是天下唯一的禁武令管不着的地方。这也好理解,//计划生育这个命令就管不了香港,澳门,当然台湾还没回来,就更//不受限制了。当然,这个命令也管不了少数民族。就是少林寺可以//练武,这当然也是有条件的:就是绝对不造反;造反一定被灭。好像//没被灭,所以肯定没造反。扯远了,goto正文;
你应该能想到了:在程序的世界,抽象的地位和少林寺在天下武功的地位是一样的!
1你还应该想到:程序中所有的概念都是以抽象为基础的。
//这句话有点空泛,有点概括性,不具体,不明确。
2你也许能想到:封装继承多态也是以抽象为基础而建立的概念。
//这句话就很具体了。
1到2就是具体化,特例化,
那么由2到1是什么呢?是概括,是泛化。其实就是抽象。
由具体到一般,这叫概括,也叫抽象。
由一般到具体,这叫具体化。
透露一点内部信息。如果你准备考南京大学的计算机研究生,那么就有用到的可能性。在面试中,如果问到OOP的三大核心是什么?就把抽象去掉,只说封装继承多态就可以了。自然是心里默念“抽风极多”,然后口头表达时把第一个略掉。如果你执意说是四个,那么老师也会认为你是对的,前提是你要把后三个说出来。
从中可以看出什么呢?在OOP中抽象相对于封装继承多态来说不是那么显赫。如果你得出抽象不重要的结论,那么你的逻辑推理能力真的有点烂,建议系统学习《逻辑学》。
抽象在面向过程编程和面向对象编程中,都是重要的!这也导致了抽象不是OOP所独有的特性,所以不如封装继承多态那么显眼。不显眼不代表不重要。在中国最不显眼的人,才是最重要的人。中国最重要的人是谁?(提示:美国最重要的人是奥巴马)你当面见过他吗?电视里见的不算。99%以上的人是没见过的,当然是非常不显眼的人。我只是想说:抽象是最重要的!抽象是程序设计的基础,是封装继承多态基础,是对象和类的桥梁。
类=f(对象),f这个函数就是抽象。意思就是把对象进行抽象,得到的结果就是类。抽象在这里也可以叫泛化。显然,抽象是有方向的,是从对象到类的。反函数呢?从类到对象呗。这叫特化。也叫实例化。
那么类和对象有什么关系呢?类是对象的抽象,对象是类的实例化。//很多书都是这么说的。
第三章 抽象之阴阳八卦
//为了顺口,其实没八卦什么事。
从中可以看出,泛化和特化是同一个现象的两个方面。就像手掌和手背。这也是我们老祖宗的阴阳学说所包含的范畴。阴阳相生,有阳必有阴,有正必有反。男人没女人,日子没法过;女人没男人,也是很凄惨。
请思考:我上面一段扯淡的目的是什么呢?抽象的对立面是存在的,就是实例化;那么封装继承多态是否存在对立面呢?
//以下三段是预告片,在抽象介绍完后才会有详细解说。
1封装有对立面,但是存在于面向过程编程中,所以不是OOP的核心。但是也是编程的重要思想,也是要必须掌握的。
2继承的对立面是派生。派生虽然是OOP的内容,但真的不是核心,一般都很少提,因为一旦发生继承,派生必然一同发生,而且是不分先后。但不是说派生不重要!相反,派生和继承一样重要。你有了孩子,你的孩子当然继承了你的优秀DNA。但是这个事件也可以这么说:你把你的优秀DNA赋予了你的孩子。编程中不说赋予,说派生,其实是一码事,仅仅是所用词汇不同。
3多态的对立面是什么呢?一态呗。一态是常态,就是正常情况下都是一态;就因为此,一态反而太普通了,所以就被人们忘记了。所以,一态这个词汇,除了本文,你还真的很难见到!但是,一态这个现象是存在的。
相信以上内容,说清楚了抽象是怎么一回事。如果你还是不理解,那么就把抽象当作概括来处理,绝对不影响使用。一遇到抽象这个词,就换成概括来理解。
第四章 抽象在程序设计中的存在形式
我把范围缩小到程序设计,介绍程序设计中的抽象是怎么一回事。
抽象是看不到的。我们只能感觉到它的存在,但是却找不到一个有形的东东来说:看,这个东东就是抽象。抽象是一种思维,是人这种高级畜生特有的功能。思维当然是看不见摸不着的了。所以,在程序设计中,我们也找不到一个语句,一个标识符,一个符号,来说这就是抽象。
我说人是高级畜生,有些人可能心里不爽;如果说是高级动物,这些人就没有不爽的感觉了。说某些人是畜生,我会道歉的,我真的感觉到了愧疚,为侮辱了畜生而彻夜难眠。。
中国人是人,这是一级抽象;人是动物,这是一级抽象;动物是生物,这也是一级抽象;
中国人是动物,这是两级抽象;中国人是生物,这是三级抽象。
显然,只有一级抽象才是不会挨揍的。我只是为了说明了一个问题:抽象是分层次的。抽象的层次性,这在程序设计中是有体现的!
对象到类,这是一级抽象;类到类模板,这也是一级抽象。
函数到函数模板,这也是一级抽象。
由于类是那么的牛X,所以,类本身也是可以分好几个层次。但是这中层次始终没有出类这个圈。如A类经一级抽象到B类,B类经一级抽象到C类;等等。ABC都还是类,即没有对象也没有类模板。如同中国人,人,动物都没有出生物这个圈。
后期预告:类内部的层次在编码实现阶段,我们有很别致的名字—继承与派生。但是,编码前的工作是什么?是设计。设计阶段我们不用继承,也不用派生,用的只有抽象。设计和编码的方向是反的!比如从n个对象抽象出类A,再从类A中抽象出类B。先有对象,才能对对象抽象啊!所以要先设计对象。自然要先有A才能抽象出B啊。所以要先设计类A。自然,最后设计类B。但是在编码阶段呢?顺序正好相反!先把类A用代码实现了,然后让类B继承A的全部特性后,再把B的自己的并且是A没有的特性用代码实现了。AB是两个类,必然有不同之处;如果完全一样,还叫两个类吗?!对象不需要编码实现,仅仅是用类实例化一下就可以。所以对OOP来说,设计主要是设计类,编码主要是实现类。
类是看不见摸不着的,但是类有大量的代码。
对象是要占据内存的,但是对象却没有代码。
这是很有意思的现象。说的是抽象,可是怎么介绍了类和对象了呢?抽象是一种思维,要以某些对象为载体!只能是某些载体之间体现了抽象,而抽象不可能脱离载体而自己存在。在OOP中,这些载体就是类和对象。
任何东西都可以用对象来表示!
未完待续-----2010年5月31日,儿童节前夜。