是什么使面向对象编程成功?[关闭]


17

您认为使面向对象编程取得如此巨大成功的功能是什么?

  1. 讯息传递
  2. 遗产
  3. 多态性
  4. 封装形式

或您可能要介绍的其他功能。

我也想知道抽象数据类型和面向对象编程之间的联系是什么?


受欢迎和成功不是同义词
凯文·克莱恩

Answers:


76

我建议面向对象编程的最重要特征是复杂性管理

人脑一次只能容纳这么多的概念-人们常常想到记住7 +/- 2个独立项目的极限。

在工作中的600kloc系统上工作时,我无法一次把整个事情都牢记在心。如果必须这样做,我将只能在小的系统上工作。

幸运的是,我不必这样做。我们在该项目中使用的各种设计模式和其他结构意味着我不必立即处理整个系统-我可以挑选单个零件并对其进行处理,因为知道它们适合更广泛的应用程序以明确的方式。

所有重要的OO概念都提供了管理复杂性的方法。

封装 -让我处理为我提供各种服务的外部API,而不必担心这些服务的实现方式。

抽象 -让我专注于基本特征,而忽略不相关的内容。

合成 -让我重复使用已经以新组合构建的组件

多态性 -让我寻求服务,而不必担心不同的对象如何以不同的方式提供它。

继承 -让我重用接口或实现,仅提供与以前不同的部分。

单一责任原则 -使每个对象的目的清晰明了,因此很容易推理

里斯科夫换人原则 -让我们不要引入奇数依赖

开放/封闭原则 -让我们以不需要我们冒险破坏现有代码的方式进行扩展和修改

依赖注入 -让我们将构成提升到一个新的水平,然后将组件组装在一起。

面向接口的开发 -让我们将抽象提升到一个新的水平,仅依赖于抽象,而不依赖于具体的实现。


6
+1。我只能投票一次,这值得我们更多的遗憾。
理查德

1
有一个必然的结论,可惜我现在找不到参考文献,但我会尽力记住要查找它并编辑评论。因此,对代码审查实践的研究发现,代码审查往往比过程代码花费更长的时间来查找OO代码中的错误,因为流程在OO代码中的跳跃更多。TDD和结对编程之类的做法可以缓解这种情况,但这仍然是一个有趣的(对我来说,是意外的)结果。

5
这可能是一个完美的答案-信息充分,但足够简短,因此读者不必阅读小说。Bravo
Tim Claason

@Graham Lee:我会对阅读该研究感兴趣。
Frank Shearar

2
@Frank @Bevan:portal.acm.org/citation.cfm

13

图形用户界面。在八十年代末,九十年代初,当Mac,Amigas,Atari ST,Windows和GEM开始取代基于字符的用户界面时,很明显,像C这样的语言并不适合编写GUI程序。尽管传统的数据处理被认为是“输入数据->处理->输出数据”模式,这也可以用过程语言来完成,但是OOs的功能可以方便地处理GUI的固有复杂性。


1
+1用于提及GUI应用程序。面向对象是允许实现GUI的工具,否则,GUI(使用过程代码)很难管理。
乔治

7

封装提供的数据隐藏。


这是答案吗?ADT提供数据隐藏功能(这就是为什么它们被称为“数据抽象”的原因)
Frank Shearar,2010年

@弗兰克,他要求提供特定的功能,当我写这个答案时,只有一个,我试图不重复。

足够公平,但是封装并不完全面向对象。我应该自己检查一下,但是我很确定我们早在面向对象之前就已经进行了封装。
Frank Shearar

1
@Frank,我同意它不是特定于OO的,它只是它的主要功能之一。

这是真正的 OOPLs,但不是全部。CLOS是一个明显的例外。
Frank Shearar

7

其他任何答案都未提及的功能:域建模。由于人们倾向于考虑使用对象或对对象进行操作,以及考虑具有固有属性的对象,因此使用面向对象的软件对问题或工作流进行建模非常容易。从本质上讲,它使我们能够利用现有的能力来处理代码中的名词,动词和形容词。


6

我认为继承是OOP最重要的一点。

[来自游戏开发]您可以创建类似Drawable的类,并具有渲染方法和属性,并创建从Drawable继承的Spaceship and Planet类。从那些对象(和其他Sprite子对象)中获取所有对象,并放入drawableObjArray,然后为每个对象调用draw方法。您只需要知道它是一个Drawable。


2
真??多态性更为重要,并且不需要继承(从理论上讲)。
Thomas Eding 2012年

甚至不需要虚函数,只需使用函数指针即可。
Calmarius 2012年

1
Alan Kay最初的OO概念甚至不包括继承,因为他不喜欢继承在以前的系统中的实现方式。
Michael Borgwardt 2012年


2

它之所以有些成功,是因为它鼓励将人类的事物组织成对象。人们通常善于观察事物之间的关系-诸如差异,相似性和行为之类的事物。OO鼓励开发模仿人类对世界的概念化的软件。

使软件开发与我们对世界的看法相似,可以使我们的头脑更轻松地处理复杂性。


也许是因为有更多的过程经验,但是在使用这两种方法之后,我仍然觉得过程比OOP更直观。不过,我仍然喜欢这两种风格的优点。
Juha Untinen 2012年

1

这里多次询问“ ADT与对象 ”。单行回答是“ ADT和对象是彼此相反的-一个人抽象得很清楚,而另一个则不能;每个对象都以不同的方式提供灵活性”。

有关更长的答案,请参见William Cook的“重新理解数据抽象”。简而言之,对象使您可以轻松地使用某些数据的多种实现/表示形式(看起来像列表的东西可能是数组,自平衡树,或...),但很难添加新操作(因为您必须将新操作添加到您的每个表示形式中),而ADT使得在数据类型上添加新操作变得容易,但是很难实现多种实现。

编辑:我曾说过,消息传递是使OO成功的原因。根据Jonas的评论,这是不对的,因为人们认为面向对象的大多数语言都不使用消息传递。由于这是不对的,因此我从回答中剔除了它。


1
消息传递几乎不能解决问题,因为没有一种成功的OOP语言使用它。
乔纳斯(Jonas)2010年

您的OO不一定是我的OO。根据Alan Kay的定义,大多数称为OO的语言都没有。我忘记了确切的引用,但是Kay说对象不是Smalltalk的重要内容,而是消息传递(并且大多数人错过了这一点)。
Frank Shearar 2010年

@Jonas我想,在重读问题和答案后,我在说一半:“ OO并不成功,因为很少有语言能正确地做到这一点。” 但是我只穿着防火服时会这样说。
Frank Shearar

0

我的前三项功能。对象组合-允许对象进行协作。多态-支持运行时的动态行为。继承-通过重用代码并通过方法重写修改行为。

ADT-即使在非面向对象的语言(例如Pascal)中,您也可以使用它。堆栈或队列是ADT的示例。


“ ADT-即使在非面向对象的语言(例如Pascal)中,您也可以拥有它。堆栈或队列是ADT的示例。”:正确。但是,OOP使定义ADT的接口和提供不同的,可互换的实现(接口/抽象类<--->子类/具体类)变得更加容易。据我所知,在Pascal中这并不容易。
Giorgio

0

用简单的话来说,OOP是可重用性和封装性的关键,它可以产生大型框架,从而使这个时代的程序员的工作变得轻松,因为它可以调用API并执行当今最想做的事情。

因为您的问题是关于OOP的4个功能,所以您可以说

  1. 继承和4。封装是最重要的功能,另外两个对于实现前两个功能非常必要

所以1.消息传递和3.多态实际上支持2.继承和4.封装。

  1. 继承和4.封装是OOP成功的关键

大多数情况下,继承不是OOP的定义组成部分,甚至不是非常理想的部分。一般而言,封装是良好的编程原则。它不是OOP发明的,也不是仅在OOP中使用。
2016年

-1

我认为,后三个功能最重要,它们影响了OOP的广泛使用:

2. Inheritance
3. Polymorphism
4. Encapsulation

编辑:另一点是IDE和图形界面开发环境,例如Visual Studio和Eclipse。由于它们包含OOP语言,因此越来越多的设计趋向于OOP。

当然,SOLID Principles是使ROCK产品可靠交付的一次尝试:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.