为什么OOP困难?[关闭]


91

当我开始使用一种面向对象的语言(Java)时,我几乎就成了“酷”并开始编码。在阅读了许多有关OOP的问题之后,直到最近我才真正考虑过它。我得到的总体印象是人们对此感到挣扎。既然我没有这么难过,也不会说我是个天才,所以我想我一定错过了一些东西或误解了。

为什么OOP难以理解?很难理解?


72
我反对:这并不难理解,只是很难掌握。这样整体编程。
史蒂文·埃弗斯

2
嗯,不是吗?也许无法编写程序的程序员发现很难责怪他们而不是他们的代码行?我不知道,但我从未听过有人说它很难理解。但是我看到ppl说函数是怪异的,特别是因为它们不能更改其变量的值。

5
@ acidzombie42:功能一点也不奇怪。您不必编写命令列表即可更改表示RAM中某个位置的变量的内容。变量代表值,您不更改值;42停留42,x停留x –不论x是多少。您可以编写从其参数映射到结果的函数。值包括:数字,值列表,从值到值的函数,产生副作用的程序以及在执行时产生的值等。这样,主函数的结果将由编译器计算,即可以执行的程序。
2011年

5
我最近一直在学习Haskell。我对函数式编程的了解和了解的越多,我就越觉得OOP很难。我认为这样做的主要原因是OOP试图将数据(对象/类)与对其进行操作的功能(方法)联系在一起。这是问题的根源,并且设计了许多OOP设计模式来避免将数据和功能捆绑在一起。例如,工厂模式用于将构造函数(它是一个函数)与其在其上操作的实际对象分开。
ming_codes 2012年

1
因为它的名字不正确。它实际上应该是面向主体的编程,因为主体执行动作(动词),而对象接收动作-约翰把球扔了。因此,johnsBall.throw()并没有任何意义。
克里斯·库德莫

Answers:


119

我个人发现OOP的机制相当容易掌握。对我来说,最困难的部分是它的“为什么”。当我第一次接触它时,它似乎是寻找问题的解决方案。我认为大多数人都很难找到这几个原因:

  1. 恕我直言,从一开始就讲OO是一个糟糕的主意。过程编码不是“坏习惯”,而是某些工作的正确工具。无论如何,OO程序中的各个方法往往看起来很程序化。此外,在足够好地学习过程编程以使其局限性变得明显之前,面向对象对学生似乎没有太大用处。

  2. 在真正掌握OO之前,您需要了解数据结构和后期绑定/高阶函数的基础。如果您甚至不了解构造数据的概念,而不是仅仅使用基元并传递高阶函数,就很难理解多态性(基本上是传递指向数据的指针和一堆对数据进行操作的函数)指向函数的指针。

  3. 设计模式应该被视为面向对象的基础知识,而不是更高级的东西。设计模式可以帮助您从树上看森林,并给出OO可以简化实际问题的相对具体示例,并且您将最终希望以任何方式学习它们。此外,一旦您真正了解了面向对象,事后看来,大多数设计模式都会变得显而易见。


5
很棒的答案,尤其是第一名。当然,OO中的方法看起来像过程语言中的方法,但是现在它们被容纳在也具有状态的对象中。
丹·罗森斯塔克

3
我特别喜欢您的第一和第三点。我的朋友喜欢设计模式,我一直告诉他,如果您仅使用良好的OOP,则大多数都非常自然地源自最初的问题。
CodexArcanum 2010年

7
+1表示“对我来说最困难的是它的“为什么””。需要花一些时间和精力才能将语言的基本知识(封装),设计原理和重构方法应用于通用解决方案(设计模式)。
Belun

12
我同意第一点,但需要注意的是,与我学习时相比,您需要向已经知道如何进行程序编程的人们更好地解释OO。不,谈论Cat继承自的类并从Mammal我们将按程序编写的真实程序中获取真实示例,这无济于事或无益。就像一个简单的数据结构。
Carson63000

4
-1今天过分强调了设计模式。当然,它们很重要,但是:首先,它们对所有范式都很重要:功能,结构化以及面向对象;其次,它们不是范式的一部分,只是许多其他可以使用的便捷附件。@SoftwareRockstar在他/她的回答中很好地解释了这一点。
CesarGon 2011年

56

我认为有些因素尚未提及。

首先,至少在一切都是对象的“纯OOP”(例如Smalltalk)中,您必须将思维转变为一种相当不自然的配置,以将数字(仅举一个例子)视为智能对象,而不是只是一个值-因为在现实中,21(例如)真的只是一个值。一方面,当您被告知OOP的一大优势是更紧密地建模现实时,这变得尤其成问题,但是您首先要从看起来像LSD启发的视图中看到很多东西,甚至是LSD的最基本和最明显的部分。现实。

其次,OOP中的继承也不是很遵循大多数人的思维模式。对于大多数人而言,最明确的分类方法没有接近创建有效的类层次结构所需的绝对规则的任何地方。特别是,创建class D从另一个继承的class B意味着class D共享对象绝对,绝对地共享的所有特征class Bclass D可以添加自己的新特征和不同特征,但必须保持所有特征class B不变。

相比之下,当人们从心理上对事物进行分类时,他们通常会遵循更为宽松的模型。例如,如果一个人对构成一类对象的规则制定了一些规则,那么只要遵循了足够多的其他规则,几乎可以打破任何一个规则。即使是一些不能真正打破的规则,也几乎总会被“拉伸”一点。

仅举例来说,将“汽车”视为一类。很容易看出,大多数人认为“汽车” 的绝大多数都有四个轮子。但是,大多数人都看过(至少是照片)只有三个轮子的汽车。我们中的一些年龄合适的人还记得80年代初(或大约20年代)有六个轮子的赛车-依此类推。这基本上给了我们三个选择:

  1. 不要断言汽车有多少个轮子-但这会导致隐含的假设,即它永远是4,并且代码可能会破坏另一个数字。
  2. 断言所有汽车都有四个车轮,即使我们知道它们确实是四个车轮,也要将其他车轮归为“非汽车”。
  3. 设计该类以允许改变车轮数量,以防万一,即使很有可能永远不需要,不会使用或经过适当测试此功能。

关于OOP的教学通常侧重于建立巨大的分类法-例如,这将是地球上所有已知生命或此顺序上的某些事物的巨大层次结构。这带来了两个问题:首先,也是最重要的是,它倾向于导致许多人专注于与眼前的问题完全无关的大量信息。在某一时刻,我看到了关于如何为狗的品种建模的漫长讨论,以及(例如)“微型贵宾犬”是否应该继承“全尺寸贵宾犬”,反之亦然,或者是否应该有一个抽象的基础“贵宾犬”类,其中“全尺寸贵宾犬”和“微型贵宾犬”都继承自它。他们所有人似乎都忽略了该应用程序应该用于跟踪狗的许可证,

其次,也是非常重要的一点,它导致关注于项目的特征,而不是关注对当前任务很重要的特征。它导致对事物进行建模,真正需要的地方(大部分时间)是构建满足我们需求的最简单模型,并使用抽象来适应必要的子类以适应我们已经构建的抽象。

最后,我再说一遍:多年来,我们正在缓慢地遵循数据库采用的相同路径。早期的数据库遵循分层模型。除了只关注数据之外,这是单一继承。在很短的时间内,一些数据库遵循了网络模型-本质上与多重继承相同(从这个角度来看,多个接口与多个基类并没有什么不同,足以引起注意或关注)。

但是,很久以前,数据库很大程度上都集中在关系模型上(尽管它们不是SQL,但在此抽象级别上,当前的“ NoSQL”数据库也是关系型的)。关系模型的优点是众所周知的,因此在这里我不再赘述。我只是注意到,我们在编程中与关系模型最接近的类比是泛型编程(很抱歉,尽管名称如此,但Java泛型实际上并没有真正的资格,尽管它们在开发过程中迈出了很小的一步。正确的方向)。


陈述得非常好,尤其是您提出的有关OOP的大多数问题不只是初学者了解它的问题,而是大多数OOP程序员学会思考的一般OOP问题。我最近一直在进行游戏设计,其中的组件模型运行得很好,它与关系模型的概念紧密相关,而不是层次结构。
CodexArcanum 2010年

7
呵呵,前几天我只是在想这个。我在OOP上阅读的所有第一本学习材料似乎都集中在继承上,而我的经验越来越多地告诉我,继承即使对人体无害,也几乎没有用。
rmac

听起来像面向表的编程,尽管我会说我逐渐意识到OOP并不是软件开发的灵丹妙药。
OnesimusUnbound,2012年

1
@OnesimusUnbound:不同之处在于泛型编程是完成某件事的一种真实,实用的方法,而面向表的编程主要是疯子对事物如何工作的理论的狂热(阅读TopMind在comp.object中的旧文章,然后您会明白我的意思-实际上,这些职位可能并不全都是陈旧的;据我所知,他一直延续到今天)。
杰里·科芬

3
这就是为什么界面如此出色的原因。您进行继承建模,并将其转换为以繁殖为先的方法。例如,以狗为例,可以假设每只狗都有一个属,并且最多可以有两个超级物种(每个亲本一个)。也可能有一个包含特性的列表属性,但是可能的变化使得将它们拔成确定的结构毫无意义。最好进行深度搜索以爬行特征并根据这些结果组合相似的品种。
伊万·普赖斯

26

OOP要求具有抽象思考的能力;很少有人真正拥有的礼物/诅咒。


35
所有编程都是抽象的。
JeffO

28
@Jeff O-我不同意。编程只需要能够告诉某人如何逐步执行某项操作的能力。如果您可以告诉别人如何制作花生酱和果冻三明治,则可以在编程界面中键入命令。与对ap,b&j三明治及其与世界的交互进行抽象建模相比,这是一种完全不同的技能。
约翰·卡夫

16
具体来说,先给某人2支铅笔,然后再给他们1支铅笔,问他们有几支铅笔。2 +1 = 3是抽象的。
JeffO

17
我同意杰夫的观点。编程基本上管理抽象。至少对于最基本的程序流程而言,这都是正确的(因为如果没有抽象,其他一切都会变得太复杂)。当新手学习如何控制抽象时,学习编程就进入了一个不同的阶段。那就是食谱隐喻掉下来的地方。编程是什么样烹饪和而单个算法可以比作一个配方,编程为执行分离的算法根本不同的。
康拉德·鲁道夫

2
@KonradRudolph大点。+1表示“如果没有抽象,其他一切都会太复杂”
Karthik Sreenivasan 2012年

21

我认为您可以这样总结基本的困难:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

当然,人们可以习惯将“ left”映射为270,是的,说“ Car.Turn”而不是“ turn the car”并不是一个巨大的飞跃。但是,要很好地处理这些对象并创建它们,您必须颠倒通常的思维方式。

我们不是在操纵对象,而是告诉对象实际上是自己做事情。也许不再感到困难,但是告诉窗口自己打开听起来很奇怪。那些不习惯这种思维方式的人必须不断地与这种奇怪作斗争,直到最终它以某种方式变得自然。


7
很好的见识。我认为问题在于,在现实生活中,与其他物体无关的“物体”所能做的事情不多。就告诉对象修改其内部状态而言,OO效果很好:矩形.enlarge(margin_in_pixels),但几年前我意识到了限制。有一天,我们的程序员正在安装硬件。有人明智地破解了“ screw.turn”。但是,这让我开始思考:当然,螺钉可以改变其方向,但这实际上是在机柜和螺钉之间进行的操作。这两个对象都不能自己完成任务。OO不够好。
DarenW,2010年

3
+1,经过多年编写“ substr(date,0,4)”之后,很难编写“ date.substring(0,4)”
ern0 2011年

4
+1为代码段。它清楚地描绘了一个实际的思考过程。
Karthik Sreenivasan 2012年

2
我实际上会将其作为您发送的命令阅读。如“告诉汽车左转”。Oop基于向对象发送消息,因此这就是我的解释方式。
bunglestink 2012年

1
好消息,所以Mayby OOP更适合于对“代理系统”进行建模?
2013年

21

对于大多数人而言,任何范例都需要一定的“边缘”推动才能掌握。根据定义,这是一种新的思维方式,因此它需要一定程度的放开旧观念,并需要一定程度的完全掌握新观念为何有用的原因。

我认为很多问题是,用于教计算机程序设计的方法通常很差。OOP现在非常普遍,以至于它不那么引人注目,但是您仍然经常在函数式编程中看到它:

  • 重要概念隐藏在奇数名称后面(FP:什么是单子?OOP:为什么有时将它们称为函数和方法)?

  • 奇怪的概念用隐喻来解释,而不是按照它们的实际用途,为什么使用它们,或者为什么有人曾经想使用它们来解释(FP:单子是太空服,它包装了一些代码。OOP:对象就像鸭子一样,可以发出声音,走路并从Animal继承)

  • 好的东西因人而异,因此对于任何学生来说,引爆点还不是很清楚,而且通常老师甚至都不记得了。(FP:哦,monad使您可以在类型本身中隐藏某些东西并继续下去,而不必每次都明确地写出正在发生的事情。OOP:哦,对象使您可以使用该数据保留某种数据的功能。)

最糟糕的是,正如问题所表明的那样,有些人会立即意识到为什么这个概念很好,而有些人则不会。这实际上取决于转折点是什么。对我而言,掌握对象存储数据和该数据的方法是关键,在此之后,其他所有内容都可以自然扩展。然后,我后来跳了起来,就像意识到从对象进行方法调用与以该对象作为第一个参数进行静态调用非常相似。

稍后会有所帮助,以帮助增进理解,但这是使一个人摆脱“ OOP没有意义,人们为什么要这么做”的最初原因。“ OOP是最好的,为什么人们还要做其他事情?”


8
我特别讨厌这种比喻,它们常常使人迷惑而不是描述。
Lie Ryan

3
“然后,我后来意识到要从对象进行方法调用与以该对象作为第一个参数进行静态调用非常相似。” 我希望从一开始就更加强调这一点,就像在Python这样的语言中一样。
Jared Updike 2010年

1
我用隐喻来解释概念的问题是老师经常停在隐喻上,好像在解释整个事情。不,这不是完整的解释。这只是一个示例,可以帮助我们围绕实际的解释进行思考。
2011年

好答案!+1表示,理解OOP的第一步将比后来的对基础知识有充分理解的自然扩展更为重要。:D
Karthik Sreenivasan 2012年

在“飞跃”学习中的同上:当我开始将OOP理解为“仅仅是”模块化/结构化/逐步构建时,但在类固醇上;当我重写了一些非常古老且难以维护的COBOL程序时。尽管我已经将OO原则应用于定制记录结构,单一用途变量以及紧密关注的模块化和结构化段落(方法),但COBOL的全球范围仍然如此。
Radarbob 2014年

15

因为OOP的基本解释与它在现场的用法几乎没有关系。大部分的教学程序都尝试使用物理模型,例如“以汽车为对象,以车轮为对象,以及门和变速器……”,但是在一些模糊的模拟编程案例之外,对象通常用于表示非物理概念或引入间接。结果是它使人们以错误的方式直观地理解它。

通过设计模式进行教学是描述OOP的一种更好的方法,因为它向程序员展示了如何用对象有效地攻击一些实际的建模问题,而不是抽象地描述它。


13

我在大多数情况下不同意dsimcha的回答:

  1. 从头开始讲面向对象本身并不是一个坏主意,讲过程语言也是如此。重要的是,我们要教人们写清晰,简洁,有凝聚力的代码,而不管面向对象还是程序性的。

  2. 好的OO程序中的单个方法根本不会成为程序性的。随着OO语言的发展(阅读C#,因为除C ++以外,我才知道这是唯一的其他OO语言)以及它们的语法越来越复杂(lambda,LINQ到对象等),这变得越来越正确。程序语言中的OO方法和过程之间唯一的相似之处是每种方法的线性本质,我怀疑这种变化很快就会改变。

  3. 您也不能在不了解数据结构的情况下掌握过程语言。指针概念对过程语言和对OO语言一样重要。例如,通过引用传递参数(这在过程语言中很常见)要求您理解指针,就像学习任何OO语言一样。

  4. 我认为根本不应该在面向对象编程的早期就教授设计模式,因为它们根本不是面向对象编程的基础。在不了解设计模式的情况下,绝对可以成为一名优秀的OO程序员。实际上,一个人甚至可以使用众所周知的设计模式,甚至不知道它们以适当的名称记录下来,也没有写过关于它们的书籍。应当从根本上讲授设计原则,例如单一职责,开放关闭和接口隔离。不幸的是,如今,许多认为自己是面向对象程序员的人要么不熟悉这个基本概念,要么只是选择忽略它,这就是为什么我们那里有那么多垃圾OO代码的原因。

要回答原始发布者的问题,是的,OO是比过程编程更难理解的概念。这是因为我们没有考虑现实生活对象的属性和方法。例如,人的大脑不会轻易将“ TurnOn”视为电视的一种方法,而是将其视为人类打开电视的功能。类似地,对于人类大脑来说,多态性是一个陌生的概念,通常只通过一个“面孔”看到每个现实对象。再次继承对我们的大脑来说不是自然的。仅仅因为我是一名开发人员,并不意味着我的儿子会成为一名开发人员。一般来说,需要对人脑进行学习以学习OO,而过程语言则更自然。


2
+1-我也不认为设计模式对于从根本上讲授OOP来说是必要的,您可以成为一名优秀的OOP程序员,并且不了解任何设计模式。另一方面,您往往会看到优秀的OOP程序员自然会出现已知的设计模式。设计模式总是发现而不是发明。
加里·威洛比

1
+1-好答案。我喜欢你所说的第四点。确实可以成为一名优秀的面向对象程序员,而无需了解真正的设计模式!
Karthik Sreenivasan 2012年

我同意#4的观点,因为大多数设计模式只不过是一种泡泡糖/管道胶带方法,用于围绕语言的局限性进行表达性编码。在其他范例中,设计模式可能完全不同,并基于其自身的约束。我不同意2,LINQ和lambda仍然以程序方式执行,它们只是提供了整齐打包的更高层次的抽象。花大量时间使用像JavaScript这样的动态类型的过程/功能语言进行开发,您会明白我的意思。
伊万·普赖斯

6

我认为许多程序员在进行前期设计和计划时会遇到困难。即使有人为您完成所有设计,仍然有可能脱离OOP原则。如果我使用一堆意大利面条代码并将其转储到一个类中,那真的是OOP吗?某些不了解OOP的人仍然可以使用Java进行编程。另外,不要将理解困难与不愿意遵循某种方法或不同意它混淆。


5

您应该阅读Objects Never?好吧,几乎没有。Mordechai Ben-Ari(需要ACM成员资格)认为OOP如此困难,因为它不是对任何事物建模的自然范式。(尽管我对此文章有所保留,因为尚不清楚他认为程序是使用OOP范式而不是使用OO语言的程序范式编写的,他认为程序需要满足什么条件。)


5

面向对象编程本身并不难。

困难的部分在于做好。在代码之间放置剪切的位置,以便可以轻松地将内容移动到通用基础对象,并在以后进行扩展?如何使您的代码可被其他人使用(扩展类,包装代理,重写方法),而无需跳过箍。

那是很难的部分,如果做得对,可能会非常优雅,如果做得不好,可能会非常笨拙。我个人的经验是,它需要大量的练习已经在所有的地方,你会希望你做的不同的情况下,才能做的不够好这个时间。


“我的个人经验是,在所有情况下都需要进行大量练习,以使您这次做得足够好。” OOP似乎是未做错方法的经过整理的清单,只有当您将所有这些方法都做错了之后,才有意义。
Jared Updike

@Jared,不完全是。将其与解决sodukus进行比较。您可以采取多种技巧来解决它,但是要想做到这一点而又不回溯,需要花费时间和实践。

如果人们将“共同基础对象”视为共同祖先,那就很清楚了。真的就是这么简单。很难理解b / c,那里有很多试图变得聪明的人误导性的解释。
2014年

4

我只是看了理查德·费曼(Richard Feynman)的一段视频,该视频讨论了人们在思考时实际上可能完全不同的方法论—我的意思是完全不同。

当我进行高级设计时,我碰巧将对象可视化,可以看到它们,看到它们的界面以及看到信息需要遍历的路径。

我也很难记住细节,并发现OO是一种很好的组织帮助-与浏览松散组织的子例程列表相比,查找功能要容易得多。

对我来说,OO是一个很大的好处,但是如果您不以相同的方式可视化或不执行高级体系结构,则它可能毫无意义且令人讨厌。


+1我的感觉也一样,但是有很多相反的方向,包括Ruby mixins ...这使您意识到严格的OO并不适合所有人。
Dan Rosenstark 2010年

@Yar Yep,这就是我所说的。尽管我个人无法想像任何更好的东西(在我使用Ruby的那一年,Ruby让我发疯了),但我开始接受每个人都有不同的看法。也许有些人在思考时会使用触摸或听觉,而不是视觉化,而OO并不会帮助他们。
Bill K

我认为这也有助于鼓励更自然的命名约定。您不再需要将函数的类型编码为函数名称(如INSTR),因为该名称已附加到类型(如string::find)上
Ken Bloom

@Ken尽管我同意,但我认为这比面向对象要强得多-Ruby有OO,但是由于鸭子输入会丢失很多类型信息-Ruby往往只说“发送”并期望您会知道必须使用哪种魔术方法才能起作用。
Bill K

@比尔,你是对的。支持通用编程的语言更多。您可以使用Haskell的模块和类型类系统获得不错的自然命名约定,而Haskell则没有面向对象。如果C已经超载,你可以得到同种通用名的C.
肯·布鲁姆

4

在介绍给OO之前,我已经做了相当多的GW-Basic和Turbo Pascal编程,所以最初它是DID

不知道这是否会发生在其他人身上,但是对我而言,就像这样:我对编程的思考过程纯粹是过程性的。如:“这样的事情会发生,然后接下来的事情会发生”,等等。我从不认为变量和数据只是程序流程中短暂的参与者。编程是“行动的流程”。

我想不容易理解(现在看来如此愚蠢)是这样一种想法,即数据/变量实际上真正重要,其意义远不只是在程序“流程”中短暂地扮演角色。或者换种说法:我一直试图通过发生的事情来理解它,而不是通过什么是它,这是掌握它的真正关键。


有趣的观点。当我努力理解庞大的C ++项目时,我想相反,主要考虑数据,即从“输入”到“输出”的位的“信号路径”。虽然我也做了很多Basic和Pascal,但我最早的技术思想是电子学。
DarenW

3

我不难理解,但是可能很多程序员对这个概念感到陌生,它们来自过程语言。

从我所见/读到的很多人(至少在论坛中)来看,他们在向OOP寻找“结果”。如果您是不回头修改程序扩展代码的过程程序员,那么可能很难理解其好处。

另外,那里有很多糟糕的OOP,如果人们正在阅读/看到它们,那么很容易理解为什么他们会感到困难。

IMO,您需要等到它“点击”或由真正有知识的人教过,我认为您不能着急。


5
如果您来自学术环境,那么您在OOP中编写的玩具程序的类型似乎也毫无意义。我从大学开始学习C语言,这很容易掌握,因为每个程序只有1页,少于100行。然后,您尝试学习OOP,这需要对象的所有这些负担和开销才能完成相同的事情,这似乎毫无意义。但是,除非您编写了一个包含许多文件和数千行的程序,否则很难理解为什么任何编程风格都很有用。
CodexArcanum 2010年

3

我认为许多人都难以理解OOP的原因是这些工具并没有真正促进它。

今天的计算机语言是计算机中正在发生的事情的抽象。

OOP是一种表示抽象的抽象方法。

因此,我们正在使用抽象来构建具有抽象的抽象。除此之外,我们抽象的内容通常是非常复杂的物理/社交交互,而且,难怪。


2

实际上,我有一个名为“面向对象编程的斗争”的博客,它源于我在学习它方面的一些挣扎。我认为这特别难理解,因为我花了很多时间使用过程编程,而且我很难理解这个想法,即对象可以由一组属性和行为表示(我习惯于只是变量和方法的集合)。

另外,有很多概念使语言面向对象-继承,接口,多态性,组成等。在真正有效地编写代码之前以及在面向对象中,确实有很多关于它的理论需要学习。方式,而在过程编程中,这仅仅是了解诸如为变量分配内存以及对其他方法的入口点调用之类的问题。


同意-面向对象的人们所面临的许多困难是他们已经训练自己“以程序方式”思考。OO并没有内在的困难,但是如果您“了解”过程技术,那么看到另一种构造事物的方式将是非常令人惊讶的。
柯克·布罗德赫斯特

毫无疑问,这是与过程编程完全不同的思维方式。但是,与许多人所说的相反,这不是A)一种不自然的思维方式,并且B)并不复杂。我只是认为这不好教。
2014年

2

动机。当您不知道为什么时,以及当您无法看清所做的事情并弄清楚自己是否做对时,很难学到一些东西。

需要的是使用OO来做有用的事情的小型项目。我建议浏览一本有关设计模式的书,并提出一本显然有用并且与OO兼容的书。(我曾经尝试过使用Strategy。像Flyweight或Singleton之类的东西会是错误的选择,因为它们通常是使用对象的方式,而不是使用对象来完成任务。)


人们总是在谈论辛格尔顿,但后来他总是被邀请参加聚会。但这是真的,他是非OO OO DP。
Dan Rosenstark 2010年

-1

我认为这取决于年龄(年龄作为经验的代表),更重要的是兴趣。如果您“年轻”(也许是绿色的),并且从未想过其他任何方式,那么这似乎很简单。另一方面,如果您认为这是您所见过的最酷的东西-28岁时发生在我身上或类似的东西-很容易gr。

另一方面,如果您认为,就像我的许多Java学生所做的那样,“我们为什么要学习它,这只是一时的风尚”,几乎是不可能学习的。大多数技术都是如此。


1
OO流行吗?您的学生几岁-我怀疑这个“时尚”比他们大(我做的第一个对象-我知道我做的-大约在1983/4年是Simula,那时Simula还不算新)
Murph

@Murph大约在2004-2005年,学生肯定超过45-50(伊比利亚的专业程序员)。
丹·罗森斯塔克

好的,我可以看一下他们是如何错过OO事情的开始的。但是到2004/5为止,我们已经很好地进入了.NET,它几乎是面向对象的(-:有些东西在开发中可能会被描述成一种时尚,但是那些没有迅速消失的东西往往会演变成好东西
Murph

1
@Murph说实话,这些家伙是他们试图转换为Java的大型机程序员。这实际上是一种有趣而独特的体验(在我的Java Trainer时代不是正常的票价)。这真实的,但是,他们所看到的东西来来去去,但显然OO比一种时尚。单独说明:我有点希望这种单元测试的东西能够流行起来,但是现在我发现我有很多单元测试要写……:)
Dan Rosenstark 2010年

-1

无论选择哪种范例(OOP,功能等),为了编写计算机程序,您都需要知道程序将执行哪些步骤。

定义流程的自然方法是写下其步骤,对于较大的任务,可以将任务分解为较小的步骤。这是程序的方式,这是计算机的工作方式,这是您逐步检查清单的方式。

OOP是另一种思维方式。您无需考虑需要逐步完成的任务清单,而是想到对象,对象的能力和关系。因此,您将编写许多对象,小的方法,并且程序将神奇地工作。为此,您需要改变主意...

这就是为什么OOP很难实现的原因。由于所有事物都是一个对象,所以他们要做的就是要求其他对象做某事,而这些其他对象基本上就是做某事。因此,OOP程序中的控件可以在对象之间疯狂地来回跳转。


-1

作为目前正在学习编程并且在这一领域有一些问题的人,我认为这个概念的具体实现并不难理解。我之所以这样说是因为我有了OOP的想法,并且已经在PHP中使用了大约一年,但是当我转向C#并查看其他程序员对对象的用法时,我发现很多人都在这样做我只是不明白。正是由于这一点,我才得以更好地理解OOP原理。

当然,我意识到这个问题很可能是我缺乏使用本机OOP语言的经验,并且随着时间的流逝,我将找到新的方法来利用对象,这对于新程序员来说就像我本人一样不清楚。目前正在经历。杰里·科芬(Jerry Coffin)谈到了几次,特别是在他的评论中:

一方面,当您被告知OOP的一大优势是更紧密地建模现实时,这变得尤其成问题,但是您首先要从看起来像LSD启发的视图中看到很多东西,甚至是LSD的最基本和最明显的部分。现实。

我发现这是非常准确的,因为看到某人为不是真的东西创建类时,我经常会得到这种印象-一个具体的例子使我无所适从,但我能即时想到的最接近的距离是一个对象(下次看到引起相同混乱的东西时,我将进行编辑)。有时,OOP似乎暂时不理会自己的规则,变得不那么直观。当对象正在生成对象,从封装它们的类继承等时,这种情况通常不会发生。

我认为对于像我这样的人,将对象的概念视为具有多个方面会有所帮助,其中之一包括在某些情况下不会像对待对象一样对待对象。诸如距离之类的东西,仅在范式上稍有变化,就可以作为一个理论对象遇到,但是却不能握在手中。我必须认为它具有一组属性,但是具有一组更为抽象的行为,例如访问其属性。我不是很确定这是我理解的关键,但似乎是我目前的研究处于领先地位。


1
一对点或对象应视为一个对象。并且距离应作为与物体的函数。使用对象并不意味着您可以从所有对象中创建对象。
Gangnus

正如我所说,距离是一个糟糕的例子。至于用万物制造物体,我指的是我所看到的正在发生的事情,而不是我实际上所做的事情-到目前为止还没有。
dsimer 2014年

这取决于语言-在SmallTalk中,距离(以及所有东西)是一个对象。但是在C#中,您提到过这将是不好的。
Gangnus 2014年

-2

在学习面向对象编程(POOP)的原理时,术语是我前进的道路。当您掌握了基本原理后,这些东西才开始逐渐成熟。就像学习新概念的所有事情都有些困难。

同意设计模式应至少与OOP平行。


-2

对我而言,主要的跃迁只是了解OOP的抽象概念。现在我对编程非常陌生,现在我已经进行了一年半的编程,所以我对OOP的介绍是使用Actionscript和Processing。当我第一次学习Actionscript编码时,它不在OOP中。我学会了直接在“动作”面板中进行编码,这就是我学习编程的基本原理(变量,函数,循环等)的方式。因此,我了解到它是直接在Flash或Processing阶段做些事情。

当OOP出现时,意识到我可以在一个对象内创建方法和属性以使其能够使用和重用,这对我来说首先很难理解。一切都非常抽象并且难以处理,但是编程语言本身要好得多,但是首先建立这些连接需要一种信念的飞跃。


哇,那没有任何意义。“一切都很抽象,很难在类和对象的实例之间进行处理。但是,一旦获得OOP,编程语言就变得更容易理解。但是,起初建立这些连接有点费力。”

-2

食谱

良好的OOP理解=良好的导师或书籍或两者兼有+个人兴趣+练习。

个人爱好

从我的个人经验来看,个人利益在指导员或好书或两者兼而有之的正确输入下,是跨过程序编程到OOP的漫长道路

实践,实践与实践

更好地了解OOP的最好朋友就是练习。这肯定会提高您的OOP能力。

俗话说:“没有什么可以代替辛勤的工作,没有成功的捷径。”

祝好运!

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.