当前位置:编程学习 > C#/ASP.NET >>

纠结 面向对象的三大特性

突然想到的一个很幼稚的问题。

面向对象有三大特性:封装,继承,多态。

为什么会有这三大特性?
三大特性是如何演变而来的(难道面向过程就没有 封装?)?
三大特性孰轻孰重? --------------------编程问答-------------------- 不要纠结字眼,我们小区门口的收破烂的还整天封装呢,但是含义是不同的。我想你完全可以轻易从入门书上找出对象(类)封装的含义,也可以找一些20年前的经典结构化软件工程的书看看它是如何封装的。 --------------------编程问答-------------------- 顺便说一下,我不知道什么时候、是什么人造出了“面向规程”这个词。

结构化、面向对象,都是在研究如何更好地表达业务对象,只不过结构化方法出现和成熟得非常早(从上世纪70年代到90年代),它因为不理解继承和多态技术所以很多东西都被淘汰了。

不知道怎么出了什么“面向过程”地说法。一切过程都是为了处理对象的,面向对象方法要编程它也要调用方法过程啊,把什么“面向过程”这个词单独贴给结构化方法就是太过分了。结构化方法只承认有组合,一切都靠功能分解、结构分解这一种思路,而视继承和多态为“魔鬼”,它无法理解一个子类实例怎么可以即继承父类的过程方法又重写过程方法,它不承认我们可以先作出原型、然后再成功推出的原型系统上通过继承、多态方式来声明一点差别就能扩展,它认为要扩展就要推倒了重新定义数据结构。 --------------------编程问答-------------------- 三大特性是怎么来的,从哲学上说,它是伴随面向对象的出现而出现。如同先有鸡还是先有蛋,用形而上学的观点很难理解。也就是sp1234所说的,“封装”在面向对象出现之前就出现了,而它最终成为面向对象核心的价值观,而面向对象的出现,又使得“封装”有了新的,具体的,特定的含义。事实上,连对象本身也是如此——在计算机出现之前,就有了对象,但是面向对象中的对象,既和原来的对象有联系,又有了独特的内涵。比如先有鸡还是先有蛋,在鸡被称之为鸡之前,就存在了某种远古鸟类,它的后代繁衍出了鸡。 --------------------编程问答-------------------- --------------------编程问答-------------------- 关于强调“封装”,是为了突出说明它是如何保证能够实现继承和多态的。正因为此,我们才同时也强调使用接口来设计和沟通(研究需求和测试,而不去争吵接口如何实现的问题)。并不是说别的方法就不封装了。Unix系统之所以流行这么多年,就是因为其结构和方法配合得几乎天衣无缝、特别优美,可见其封装是非常高超的,例如对各种子系统模块都有抽象。只不过,许多封装概念都停留在文献说明上,而并没有使用一种OOPL语言那样的强类型的方式来清晰地表达,也就是说其在思想上是比现在大多数人写的程序都更加面向对象的,但是其代码不是成文自明的。

现在的“封装”概念更多地是从OOPL语言出发,这样不同的人写的面向对象代码可能更容易像一个头脑想出来的似地,都是从实际业务模型直接分析出来的,而不是用大堆计算机领域的数据类型。

不过,虽然过了20年,几乎所有结构化编程者都是用面向对象语言,甚至他也可以煞有介事地用UML等等语言来跟别人讨论面向对象方式的设计思路,但是他一写出代码却又回到结构化的老路上去了,这种人非常多。 --------------------编程问答-------------------- 很多人都背书般的知道OO,也知道OO有封装、继承、多态,却不知OO的目的,只知道为了封装而封装,为了继承而继承,为了多态而多态,实属“没事找抽”型。实乃当今教育之误。
古时候说话,叫:知其所以然,竞不知其然,是也。

封装、继承、多态是OO提供的手段,那么其目的是什么呢?记住:无他,开闭原则也。
以下摘自Wiki:
引用
Open/closed principle

the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"


用封装来实现closed for modification,用继承、多态来实现open for extension。

BTW:楼主能提出如此问题,即说明教育的缺失,也说明楼主敏学善思,孺子可教也 --------------------编程问答-------------------- 在早期有很多基于对象的扩展的例子。例如假设要用汇编语言写一个notepad.exe程序,假设定义了一个STRUCT Command1用来保存一个“删除一些单词”命令,这个STRUCT对应地在另一个方法TABLE中有几个程序入口地址分别对应着不同方法。假设需要扩展它为“删除恰好一个句子”命令,那么可能会定义另外一个STRUCT Command2,这个结构中第一个单元是声明为STRUCT1的,也就是说如果说对于Command1类型的数据从起始地址第5个字节是一个关于此命令的“被删除的字符的列表指针”数据,那么对于Command2其实也是,因为Command2其实首先组合了Command1结构。于是,对于方法表上针对Command1结构的方法调用,其实有的也可以用于针对Command2类型的数据调用,这似乎有点像是方法继承了。这类编程设计技巧在早期的各种优秀系统中,我相信非常非常普遍,只不过没有总结为什么面向对象理论,而是被看作属于黑客惯用的伎俩,但是是非常管用的伎俩。这对于c语言编程也是一样的。

但是这种滥用指针既给一些黑客带来了方便,也给更加广大的普通程序员带来了麻烦不断。

那么要继承这种黑客编程方法,比如要继承使用回调的方法,可是又希望从此摆脱滥用指针的困扰,那么就只有理论上成熟起来,出现了所谓的面向对象编程语言标榜的新的封装方法,比如说你使用 x.method() 代码来先在调用方法表上查询然后使用指针调用方法,你可以使用virtual/override方法来重写方法表,你使用Delegate来处理回调(甚至事件机制),等等,这些都跟你使用c语言(我不是指c++)编程有天壤之别。

显然我们不能说因为使用了OOPL语言,我们就比40年前的那一大批软件开发黑客、或者20年前面向对象OOAD理论成熟之前的开发人员水平更高。他们比我们年长30岁,也许编程水平仍然比我们不差,可能是因为他们在思想上跟我们对编程的认识根本不同,他们使用基本c可以编写出的普通MIS软件也比我们的用c#写的好,只不过是现在他们在基本c中找不到像.net类库这么强大的类库所以才不得不放弃c等等顺手的工具。 --------------------编程问答-------------------- 在以前我在工作中遇到过不少用了十几年的BASIC、c程序,(当时)大型机构用的,可以用十几年而不被替换掉可见其水平。可是我们现在动用了关系,再加上社会进步很快,用户很快就把过去的老程序换掉了,现在的开发工具多么“简单方便”,随便就能拼凑了东西出来,可是软件业已经有些滥了。 --------------------编程问答-------------------- 甚至他也可以煞有介事地用UML等等语言来跟别人讨论面向对象方式的设计思路,但是他一写出代码却又回到结构化的老路上去了,这种人非常多。


见解独到,阅历无数程序员啊!赞! --------------------编程问答-------------------- 自卑了,原来我一直都只停留在OOPL基础上的继承、封装和多态。

--------------------编程问答-------------------- 1.先弄清楚OOD和OOP的区别
  面向对象设计:统一描述,UM(不是UML),
  面向对象第一推导:MVC,M=发现抽象;C=发明策略;V=提供服务,
  真正的好的设计是,在不同粒度上,组件或者系统的组织形式都是MVC的;

2.楼主所说的三个OOP的特性是为了满足OOD的实施需求应运而生的,
  楼主还漏了一个重要的特性:消息 --------------------编程问答-------------------- 都是夜猫子,小心身体。 --------------------编程问答-------------------- 见解独到,阅历无数程序员啊!赞! --------------------编程问答-------------------- --------------------编程问答-------------------- 受教了 --------------------编程问答-------------------- 小区门口的只装不封吧..... --------------------编程问答-------------------- 学习了 --------------------编程问答-------------------- 一字千里呀!!!! --------------------编程问答-------------------- 学习。 --------------------编程问答-------------------- 好,路过学习! --------------------编程问答-------------------- 都是大牛,学习了。 --------------------编程问答-------------------- 我了个擦 --------------------编程问答-------------------- 一觉醒来,竟错过了这么好的东西 --------------------编程问答-------------------- LS都是通宵之人啊 --------------------编程问答-------------------- 都是通宵之人 --------------------编程问答-------------------- 能挣到钱才是王道 --------------------编程问答-------------------- ,面向对象的确能解决软件研发中很多问题,值得深究 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 学习中  受教了!!! --------------------编程问答--------------------
引用 3 楼 caozhy 的回复:
三大特性是怎么来的,从哲学上说,它是伴随面向对象的出现而出现。如同先有鸡还是先有蛋,用形而上学的观点很难理解。也就是sp1234所说的,“封装”在面向对象出现之前就出现了,而它最终成为面向对象核心的价值观,而面向对象的出现,又使得“封装”有了新的,具体的,特定的含义。事实上,连对象本身也是如此——在计算机出现之前,就有了对象,但是面向对象中的对象,既和原来的对象有联系,又有了独特的内涵。比如先有鸡……

正如3楼所说,一个新事物的诞生,是需要许多理论或者概念的支持,既然称之为特性,就应该是其他所没有的特性啦。 --------------------编程问答--------------------
引用楼主 cosmokey 的回复:
突然想到的一个很幼稚的问题。

面向对象有三大特性:封装,继承,多态。

为什么会有这三大特性?
三大特性是如何演变而来的(难道面向过程就没有 封装?)?
三大特性孰轻孰重?


哈哈,经典,面向对象就是面向生活 --------------------编程问答-------------------- 上面所有人的回答都是狗屎,云了半天,说了一堆,都是菜,
OO最核心的作用就是灵活的模块化和较高的复用性,所有的一切特性都是奔着这两点展开的!
  就这么简单的东西还要长篇大论,都是草苞,, --------------------编程问答-------------------- 面向对象应该是一种设计思路,封装,多态,继承是三种工具 --------------------编程问答-------------------- 来看大牛! --------------------编程问答-------------------- OOP需要在实践中不断体会和提高吧。我曾经听一个项目经理对一个同事说,你提交的代码我看不懂,没有面向对象的意思。呵呵。多观摩有质量的代码,慢慢的提高 --------------------编程问答-------------------- 学习了 --------------------编程问答-------------------- 好久没温习了。。。 --------------------编程问答-------------------- 占楼学习 --------------------编程问答-------------------- 这个需要好好学习 --------------------编程问答-------------------- 楼上诸多见解都另人佩服。最终目的都是为了实现目的。目的相同,实现方式不同,也就是殊途同归。 --------------------编程问答-------------------- 这问题…… --------------------编程问答-------------------- 果然都是高手啊,呼呼。多多学习下! --------------------编程问答-------------------- 说的很不错  大牛就是不一样啊 --------------------编程问答-------------------- 注意身体啊!年纪大的孩子伤不起啊 --------------------编程问答-------------------- 学习了学习了 --------------------编程问答-------------------- 学习了 --------------------编程问答--------------------
引用 33 楼 righthook8 的回复:
上面所有人的回答都是狗屎,云了半天,说了一堆,都是菜,
OO最核心的作用就是灵活的模块化和较高的复用性,所有的一切特性都是奔着这两点展开的!
  就这么简单的东西还要长篇大论,都是草苞,,

是啊,关键还是看你对象的属性和方法总结得怎么样(封装),复用和扩展得怎么样(继承和多态)。长篇的思想是OO大师级人物探讨的 --------------------编程问答-------------------- 都是夜猫子啊 --------------------编程问答-------------------- 学习了!各位先驱见地真是另人茅塞顿开 --------------------编程问答-------------------- 膜拜大牛,学习了 --------------------编程问答-------------------- 顶一个 --------------------编程问答-------------------- 膜拜各种牛人,呵呵 --------------------编程问答-------------------- 在我刚毕业时,一个香港公司的HR问我这个我没回答上来,于是就不要我了.
哈哈哈哈 --------------------编程问答-------------------- 封装:
使得代码规模能够达到更高的级别
因为编译器可以通过封装来检查你的很多错误,可以减少我们被错误的困扰,自然就可以写出更大规模的代码

继承:
使得代码能够得到更好的重用
做同样的事情,可以使用更少的代码

多态:
使得代码能够更好地扩展
现在写的代码可以为以后的补充留有余地;在原来的代码基础上开发的时候,不必去更改原来的代码


总之,这个些通特性的目的只有一个:
能够让代码完成更复杂的工作

这是我的个人理解 --------------------编程问答-------------------- 路过,学习,学习 --------------------编程问答-------------------- 面向对象只不过是为了一句话,高内聚,低耦合 --------------------编程问答-------------------- --------------------编程问答-------------------- 学习下。额, --------------------编程问答-------------------- --------------------编程问答-------------------- 嗯,这东西有一定哲学上的深思,但是灵活运用是比较重要的

深层次的理解,灵活的运用

钱钱钱钱!时间,安全这两点可能永远都是宝 --------------------编程问答-------------------- --------------------编程问答-------------------- 受教了 --------------------编程问答-------------------- xuexi le --------------------编程问答-------------------- 学习了 --------------------编程问答-------------------- 牛人们,小心身体啊,你们是国家的栋梁啊,身体本钱,本钱。 --------------------编程问答-------------------- 不要纠结字眼,我们小区门口的收破烂的还整天封装呢,但是含义是不同的。我想你完全可以轻易从入门书上找出对象(类)封装的含义,也可以找一些20年前的经典结构化软件工程的书看看它是如何封装的。 --------------------编程问答-------------------- study. --------------------编程问答-------------------- 先学一些设计模式再来看三大特性,也许知道为什么有这三野。 --------------------编程问答-------------------- 再说一句,没有需求的变化就用不着搞这些东东。 --------------------编程问答-------------------- 声明:偶不是来打酱油滴!! --------------------编程问答-------------------- 受教了! --------------------编程问答-------------------- 进来了解啊。。。。。。。 --------------------编程问答-------------------- 路过帮顶  --------------------编程问答-------------------- 学习了,谢谢! --------------------编程问答-------------------- 学习下 --------------------编程问答-------------------- 学习下 --------------------编程问答-------------------- 面向对象有点深奥啊。 我也就知道封装、继承、多态。这个需要多了解 慢慢就会了 --------------------编程问答--------------------   受教!!!!!!!! --------------------编程问答-------------------- 好贴。。 --------------------编程问答-------------------- 领教学习了 谢谢 --------------------编程问答-------------------- 学习,高人无数! --------------------编程问答-------------------- 谢谢,无私分享 --------------------编程问答-------------------- 楼主很好学。

面向对象为何是这个样子?
这是由面向对象要解决的问题决定的。
建议看看 《面向对象分析与设计(第三版)》[美]Grady Booch
本书用了4章来解释这个问题。 --------------------编程问答-------------------- 还没到纠结的程度
--reply by CSDN Study V1.0.0.3 (starts_2000) --------------------编程问答-------------------- 学习了,受益匪浅 --------------------编程问答--------------------
引用 80 楼 wxr0323 的回复:
好贴。。

接粉界的最牛的人出现了,, --------------------编程问答-------------------- 不好比较,没有孰轻孰重
三大特性为的是代码简化,有面向对象思想 --------------------编程问答-------------------- 先接个粉 --------------------编程问答-------------------- 都是大能,我发现我还要学习英语 --------------------编程问答-------------------- 学习的! --------------------编程问答-------------------- 我只是来学习的! --------------------编程问答-------------------- 学习学习 --------------------编程问答-------------------- 最怕别人把面向对象和哲学绑在一起讨论! --------------------编程问答-------------------- 额,终于发现哲学跟对象也扯上钩了 --------------------编程问答-------------------- 都很有才哪。 --------------------编程问答-------------------- 这都能行。。。 --------------------编程问答--------------------
引用 55 楼 icedmilk 的回复:
封装:
使得代码规模能够达到更高的级别
因为编译器可以通过封装来检查你的很多错误,可以减少我们被错误的困扰,自然就可以写出更大规模的代码

继承:
使得代码能够得到更好的重用
做同样的事情,可以使用更少的代码

多态:
使得代码能够更好地扩展
现在写的代码可以为以后的补充留有余地;在原来的代码基础上开发的时候,不必去更改原来的代码


总之,这个些通特性的目的只有一个:……

很同意。这样的说法。
面向对象的目的,是为了解决“软件危机”。 --------------------编程问答-------------------- ...用不着上升到哲学角度吧 --------------------编程问答-------------------- 幼儿园分为小托班,托班,小班,中班,大班,那么封装是小托班,多态是托班而已,继承是中班的内容,如果继承结合重写、抽象等理解的好,就可以上学了,具体到编程上,封装和多态并不能解决诸如代码冗余、高耦合,复用性差等问题,而继承+抽象+重写可以
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,