当我开始使用一种面向对象的语言(Java)时,我几乎就开始“酷”并开始编码。在阅读了许多有关OOP的问题之后,直到最近我才真正考虑过它。我得到的总体印象是人们对此感到挣扎。既然我没有这么难过,也不会说我是个天才,所以我想我一定错过了一些东西或误解了。
为什么OOP很难理解?很难理解吗?
#1 楼
我个人发现OOP的机制相当容易掌握。对我来说最困难的部分是它的“为什么”。当我第一次接触它时,它似乎是寻找问题的解决方案。以下是我认为大多数人都很难做到的几个原因:恕我直言,从一开始就讲授面向对象是一个可怕的想法。程序编码不是“坏习惯”,它是某些工作的正确工具。无论如何,OO程序中的各个方法往往看起来很程序化。此外,在足够好地学习过程编程以使它的局限性变得显而易见之前,面向对象的学习对学生似乎不是很有用。
在真正掌握面向对象之前,您需要了解数据结构和后期绑定/的基础知识。高阶函数。如果您甚至不了解构造数据的概念,而不是仅仅使用基元并传递高阶函数,就很难理解多态性(基本上是传递指向数据的指针和一堆对数据进行操作的函数)函数的指针。
设计模式应该作为面向对象的基础,而不是更高级的。设计模式可以帮助您从树上看森林,并给出相对具体的示例,以了解OO可以简化实际问题,并且您最终将想要学习它们。此外,一旦您真正了解了面向对象,大多数设计模式在事后都会变得显而易见。
评论
很棒的答案,尤其是第一名。当然,OO中的方法看起来像过程语言中的方法,但是现在它们被容纳在也具有状态的对象中。
–丹·罗森斯塔克(Dan Rosenstark)
2010年11月1日于14:21
我特别喜欢您的第一和第三点。我的朋友喜欢设计模式,我一直告诉他,如果您仅使用良好的OOP,则大多数都非常自然地源自最初的问题。
– CodexArcanum
2010年11月1日14:35
+1表示“对我来说最困难的部分是它的“原因””。需要花一些时间和精力才能将语言的基本知识(封装),设计原理和重构方法应用于通用解决方案(设计模式)。
–贝伦
2010年11月1日15:34
我同意第一点,但需要注意的是,与我学习时相比,您需要更好地向已经知道如何进行程序编程的人们解释OO。不,谈论从哺乳动物继承的Cat类,使用我们将按程序编写的真实程序中的真实示例,这是没有用的,也不是有益的。就像一个简单的数据结构。
– Carson63000
2010年11月1日于22:58
-1今天过分强调了设计模式。当然,它们很重要,但是:首先,它们对所有范式都很重要:功能,结构化以及面向对象;第二,它们不是范式的一部分,只是许多其他可以使用的便捷附件。 @SoftwareRockstar在他/她的回答中很好地解释了这一点。
– CesarGon
2011-2-11在9:36
#2 楼
我认为有些因素尚未提及。首先,至少在“纯OOP”(例如Smalltalk)中,凡事都是对象,您必须将思维转变为一种不自然的配置,以想到一个数字(仅适用于一个)例如)作为一个智能对象,而不仅仅是一个值-因为实际上,
21
(例如)实际上只是一个值。一方面,当您被告知OOP的一大优势是更紧密地建模现实时,这变得尤其成问题,但您首先要从看起来像LSD启发的视图中看到很多东西,甚至是LSD的最基本和最明显的部分。 其次,OOP中的继承也不是很遵循大多数人的思维模式。对于大多数人而言,最明确的分类方法没有接近创建有效的类层次结构所必需的绝对规则的任何地方。特别是,创建从另一个
class D
继承的class B
意味着class D
的对象绝对共享,肯定具有class B
的所有特征。 class D
可以添加自己的新特性和不同特性,但是class B
的所有特性必须保持不变。相反,当人们从心理上对事物进行分类时,它们通常遵循更为宽松的模型。例如,如果一个人对构成一类对象的规则制定了一些规则,那么只要遵循了足够多的其他规则,几乎任何一条规则都可以被打破,这是很典型的。即使是一些无法真正打破的规则,也几乎总会被“拉伸”。
仅举例来说,将“汽车”视为一类。很容易看出,大多数人认为“汽车”的绝大多数都有四个轮子。但是,大多数人都看过(至少是照片)只有三个轮子的汽车。我们中的一些年龄合适的人还记得80年代初(或大约20年代)有六个轮子的赛车-依此类推。这基本上给了我们三个选择:
不要断言汽车有多少个轮子-但这会导致隐含的假设,即它永远是4 ,以及可能会破译另一个数字的代码。
断言所有汽车都有四个车轮,即使我们知道它们确实是四个车轮,也要将它们归类为“非汽车”。
设计该类以允许轮数的变化,以防万一,即使很有可能永远也不需要,不会使用或经过适当的测试。
关于OOP的教学通常侧重于建立巨大的分类法-例如,这将是地球上所有已知生命或此秩序上某个事物的巨大层次结构。这带来了两个问题:首先,也是最重要的是,它趋向于导致许多人专注于与眼前的问题完全无关的大量信息。在某一时刻,我看到了关于如何为犬种建模的漫长讨论,以及(例如)“迷你贵宾犬”是否应该继承“全尺寸贵宾犬”,反之亦然,或者是否应该有一个抽象的基础“贵宾犬”类,其中“全尺寸贵宾犬”和“微型贵宾犬”都继承自它。他们似乎都忽略了该应用程序应该用于跟踪狗的许可证,并且出于手头的目的,只需要一个名为“品种”(或该顺序的名称)的字段就足够了。完全建立品种之间关系的模型。
其次,也是非常重要的一点,它导致关注于项目的特征,而不关注于对当前任务很重要的特征。它导致对事物进行建模,真正需要的地方(大部分时间)是构建满足我们需求的最简单模型,并使用抽象来适应必要的子类以适应我们已经构建的抽象。 br />
最后,我再说一遍:多年来,我们正在缓慢地遵循数据库所采用的相同路径。早期的数据库遵循分层模型。除了只关注数据之外,这是单一继承。在很短的时间内,一些数据库遵循了网络模型-本质上与多重继承相同(从这个角度来看,多个接口与多个基类并没有什么不同,足以引起注意或关注)。
但是,很久以前,数据库很大程度上都集中在关系模型上(尽管它们不是SQL,但在这种抽象级别上,当前的“ NoSQL”数据库也是关系数据库)。关系模型的优点是众所周知的,因此在这里我不再赘述。我只是注意到,我们在编程中与关系模型最接近的类比是泛型编程(很抱歉,尽管名称如此,但Java泛型实际上并没有真正的资格,尽管它们在开发过程中迈出了很小的一步。正确的方向)。
评论
陈述得非常好,尤其是您所遇到的有关OOP的大多数问题不只是初学者了解它的问题,而是大多数OOP程序员学会思考的一般OOP问题。我最近一直在进行游戏设计,其中的组件模型运行得很好,它与关系模型的概念紧密相关,而不是层次结构。
– CodexArcanum
2010年11月1日于16:47
呵呵,前几天我只是在想这个。我在OOP上阅读的所有第一本学习资料似乎都集中在继承上,而我的经验越来越多地告诉我,继承即使对人体无害,也几乎没有用。
–rmac
2010年11月1日,19:45
听起来像面向表的编程,尽管我会说,我逐渐意识到OOP不是软件开发的灵丹妙药。
– OnesimusUnbound
2012年1月9日在16:31
@OnesimusUnbound:区别在于泛型编程是完成某件事的一种真正实用的方法,而面向表的编程主要是疯子对事物如何工作的理论的狂热(请阅读TopMind在comp.object中的旧文章,然后您“我会明白我的意思-实际上,这些职位可能并不全都是陈旧的;据我所知,他一直延续到今天)。
–杰里·科芬(Jerry Coffin)
2012年1月9日17:23
这就是为什么界面如此出色的原因。您进行继承建模,并将其转换为以繁殖为先的方法。例如,以狗为例,可以假定每只狗都有一个属,并且最多可以有两个超级物种(每个亲本一个)。可能还会有一个包含特性的列表属性,但是可能的变化使得将它们变成确定的结构毫无意义。最好进行深度搜索以爬行特征并根据这些结果组合相似的品种。
–伊文·普莱斯
2012年8月15日在22:12
#3 楼
OOP要求具有抽象思考的能力;很少有人甚至专业程序员真正拥有的礼物/诅咒。评论
所有编程都是抽象的。
– JeffO
2010年11月1日13:47
@Jeff O-我不同意。编程仅需要能够告诉某人如何逐步执行某项操作的能力。如果您可以告诉某人如何制作花生酱和果冻三明治,则可以在编程界面中键入命令。与对p,b&j三明治及其与世界的交互方式进行抽象建模相比,这是完全不同的技能。
–约翰·卡夫(John Kraft)
2010年11月1日于13:54
具体来说,先给某人2支铅笔,然后再给他们1支铅笔,问他们有几支铅笔。 2 +1 = 3是抽象的。
– JeffO
2010年11月1日于15:53
我同意杰夫的观点。编程基本上是管理抽象。至少对于最基本的程序流程来说,这都是正确的(因为如果没有抽象,其他一切都会变得太复杂)。当新手学习如何控制抽象时,学习编程就进入了一个不同的阶段。那就是食谱隐喻掉下来的地方。编程与烹饪完全不同,虽然可以将单个算法比作菜谱,但编程与实现隔离算法根本不同。
–康拉德·鲁道夫(Konrad Rudolph)
10-11-1在16:24
@KonradRudolph大点。 +1表示“如果没有抽象,其他一切都会太复杂”。
– Karthik Sreenivasan
2012年1月24日下午5:32
#4 楼
我想您可以这样总结基本的困难:// 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 “转弯”而不是“转弯汽车”并不是一个巨大的飞跃。但是,要很好地处理这些对象并创建它们,您必须颠倒通常的思维方式。
我们不是在操纵对象,而是在告诉对象实际独立地做事。可能不再感到困难,但是告诉窗口自己打开听起来很奇怪。不习惯这种思维方式的人们必须不断地与这种怪异作斗争,直到最终它以某种方式变得自然。
评论
很好的见识。我认为问题在于,在现实生活中,与其他物体无关的“物体”所能做的事情不多。就告诉对象修改其内部状态而言,OO效果很好:矩形.enlarge(margin_in_pixels),但几年前我意识到了限制。有一天,我们的程序员正在安装硬件。有人明智地破解了“ screw.turn”。但是,这让我开始思考:当然,螺钉可以改变其方向,但这实际上是在机柜和螺钉之间进行的操作。这两个对象都不能自己完成任务。 OO不够好。
– DarenW
2010年11月13日,0:18
+1,经过多年编写“ substr(date,0,4)”之后,很难编写“ date.substring(0,4)”
–ern0
2011年1月23日在22:37
+1为代码段。它清楚地描绘了一个实际的思考过程。
– Karthik Sreenivasan
2012年1月24日5:50
我实际上会将其作为您发送的命令阅读。如“告诉汽车左转弯”。 Oop基于向对象发送消息,因此这就是我的解释方式。
–废纸t
2012年6月22日下午2:55
洞察力强,因此OOP也许更适合于对“代理系统”进行建模?
– Qbik
13年3月2日,16:32
#5 楼
对于大多数人来说,任何范例都需要一定的“边缘”推动才能掌握。根据定义,这是一种新的思维方式,因此它需要一定程度的放开旧观念,并需要一定程度的完全掌握新观念为何有用的原因。我认为很多问题是,用于教授计算机编程的方法通常很差。 OOP现在是如此普遍,以至于它不那么引人注目,但您仍然在函数式编程中经常看到它:
重要的概念隐藏在奇数名称后面(FP:什么是单子?OOP:为什么他们有时会称它们为函数,有时又称其为方法吗?)
奇数的概念是用隐喻来解释的,而不是根据它们的实际作用,为什么使用它们或为什么有人曾想使用它们来解释(FP :一个monad是一个太空服,它包装了一些代码OOP:一个对象就像鸭子,它可以发出声音,走路并从Animal继承)
好东西因人而异,因此并不完全清楚什么将成为任何学生的转折点,并且通常老师甚至不记得了。 (FP:哦,monad使您可以在类型本身中隐藏某些东西并继续下去,而不必每次都明确地写出正在发生的事情。OOP:哦,对象使您可以使用该数据保留某种数据的功能。)
最糟糕的是,正如问题所表明的那样,有些人会立即认清为什么这个概念很好,而有些人则不会。这实际上取决于转折点是什么。对我而言,掌握对象存储数据和该数据的方法是关键,在此之后,其他所有内容都可以自然地扩展。然后,我后来跳了起来,就像意识到从对象进行方法调用与以该对象作为第一个参数进行静态调用非常相似。
稍后会有所帮助,以帮助增进理解,但这是使一个人摆脱“ OOP毫无意义,为什么人们这样做的原因”的最初原因。到“ OOP是最好的,人们为什么还要做其他事情?”
评论
我特别讨厌这种比喻,他们常常混淆而不是描述它们。
– Lie Ryan
2010年11月1日于17:20
“然后,我后来跳了起来,就像意识到从对象进行方法调用与以该对象作为第一个参数进行静态调用非常相似。”我希望从一开始就更加强调这一点,就像在Python这样的语言中一样。
–Jared Updike
2010年11月1日于20:43
我用隐喻来解释概念的问题是老师经常停在隐喻上,好像在解释整个事情。不,这不是完整的解释。这只是一个示例,可以帮助我们围绕实际的解释进行思考。
–跳楼
2011年6月29日15:36
好答案! +1表示,理解OOP的第一步将比后来的对基础知识有很好的理解的自然扩展更为重要。 :D
– Karthik Sreenivasan
2012年1月24日下午5:40
在“飞跃”学习中的同上:当我开始将OOP理解为“仅仅是”模块化/结构化/逐步构建时,但在类固醇上;当我重写了一些非常古老且难以维护的COBOL程序时。尽管COBOL的全球范围很广,但我实际上已将OO原则应用于自定义记录结构,单一用途变量以及紧密关注的模块化和结构化段落(方法)。
– radarbob
2014年11月6日4:45
#6 楼
因为OOP的基本解释与它在现场的用法几乎没有关系。大多数用于教学的程序都尝试使用物理模型,例如“以汽车为对象,以车轮为对象,以及门和变速器……”,但是在一些模糊的模拟编程案例之外,对象通常用于表示非物理概念或引入间接。其效果是使人们以错误的方式直观地理解它。从设计模式中进行教学是描述OOP的一种更好的方法,因为它向程序员展示了如何使用这些方法可以有效地解决一些实际的建模问题。对象,而不是抽象地描述它。
#7 楼
我在大多数情况下不同意dsimcha的回答:从一开始教OO本身并不是一个坏主意,教学过程语言也不是一个坏主意。重要的是,我们要教人们写清晰,简洁,有凝聚力的代码,而不管OO或过程如何。
好的OO程序中的各个方法根本不会成为过程性的。随着OO语言的发展(阅读C#,因为除C ++以外,我才知道这是唯一的其他OO语言)以及它们的语法越来越复杂(lambda,LINQ到对象等),这种情况变得越来越真实。程序语言中的OO方法和过程之间唯一的相似之处是每种方法的线性本质,我怀疑这很快就会改变。
如果不了解数据结构,您也无法掌握一种程序语言。指针概念对过程语言和对OO语言一样重要。例如,通过引用传递参数(这在过程语言中很常见)要求您理解指针,就像学习任何OO语言一样。
我不认为应该在OO早期就教授设计模式。根本不编程,因为它们根本不是面向对象编程的基础。在不了解设计模式的情况下,绝对可以成为一名优秀的面向对象程序员。实际上,一个人甚至可以使用众所周知的设计模式,甚至不知道它们以适当的名称记录下来,也没有写过关于它们的书。应该从根本上讲授设计原则,例如单一职责,开放关闭和接口隔离。不幸的是,如今许多认为自己是面向对象程序员的人要么不熟悉这个基本概念,要么只是选择忽略它,这就是为什么我们那里有那么多垃圾OO代码的原因。只有对这些原则和其他原则有透彻的了解之后,才能介绍设计模式。
要回答原始发布者的问题,是的,OO是比过程编程更难理解的概念。这是因为我们没有考虑现实生活对象的属性和方法。例如,人的大脑并不容易将“ TurnOn”视为电视的一种方法,而是将其视为人类打开电视的功能。类似地,对于人类大脑来说,多态性是一个陌生的概念,通常只通过一个“面孔”就能看到每个现实对象。再次继承对我们的大脑来说不是自然的。仅仅因为我是一名开发人员,并不意味着我的儿子会成为一名开发人员。一般来说,需要对人的大脑进行培训以学习OO,而过程语言则更自然。
评论
+1-我也不认为在基本的OOP教学中设计模式是不必要的,您可以成为一名优秀的OOP程序员,并且不了解任何设计模式。另一方面,您倾向于看到优秀的OOP程序员自然会出现已知的设计模式。设计模式总是发现而不是发明。
–加里·威洛比(Gary Willoughby)
2010-11-2 20:10
+1-好答案。我喜欢你所说的第四点。确实可以成为一名优秀的OO程序员,而无需了解真正的设计模式!
– Karthik Sreenivasan
2012年1月24日5:47
我同意#4的观点,因为大多数设计模式只不过是一种泡泡糖/管道胶带方法,用于围绕语言的局限性进行表达。在其他范例中,设计模式可能完全不同,并基于其自身的约束。我不同意2,LINQ和lambda仍然以程序方式执行,它们只是提供了整齐打包的更高层次的抽象。用动态类型的过程/功能语言(如JavaScript)花费大量时间进行开发,您会明白我的意思。
–伊文·普莱斯
2012年8月15日在22:40
#8 楼
我认为许多程序员在开始时就很难进行前期设计和规划。即使有人为您完成所有设计,仍然有可能脱离OOP原则。如果我使用一堆意大利面条代码并将其转储到一个类中,那真的是OOP吗?某些不了解OOP的人仍然可以使用Java进行编程。另外,不要将理解困难与不愿意遵循某种方法或不同意它混淆。#9 楼
您应该阅读Objects Never?好吧,几乎没有。 Mordechai Ben-Ari(需要ACM成员资格)认为OOP如此困难,因为它不是对任何事物建模的自然范式。 (尽管我对此文章有所保留,因为尚不清楚他认为程序是使用OOP范式而不是使用OO语言编写的程序范式,他认为程序需要满足什么条件。)#10 楼
面向对象编程本身并不难。做起来很难。在代码之间放置剪切的位置,以便可以轻松地将内容移动到通用基础对象,并在以后进行扩展?如何使您的代码可被其他人使用(扩展类,包装代理,覆盖方法),而无需跳过箍。
那是很难的部分,如果做得对,可能会非常优雅,如果做得不好,会变得非常笨拙。我的个人经验是,在所有情况下都需要进行大量练习,以使您这次做得足够好。
评论
“我的个人经验是,在所有情况下都需要大量练习,以便您希望自己做得不同,以便这次做得足够好。” OOP似乎是没有做错方法的经过整理的清单,只有在所有这些方法都做错了之后,才有意义。
–Jared Updike
2010年11月1日于20:51
@Jared,不完全是。将其与解决sodukus进行比较。您可以采取多种技巧来解决该问题,但是要想做到这一点而无需回溯,需要花费时间和实践。
–user1249
2010年11月1日在21:17
如果人们将“共同基础对象”视为共同祖先,那么就很清楚了。真的就是这么简单。很难理解b / c,那里有很多试图变得聪明的人误导性的解释。
–annoying_squid
2014年7月22日在20:31
#11 楼
我只是看了理查德·费曼(Richard Feynman)的一段视频,该视频讨论了人们在思考时可能实际上完全不同的方法。我的意思是完全不同。当我进行高级设计时,我碰巧可视化对象,我可以看到它们,看到它们的界面,以及信息需要穿越的路径。
我也很难记住细节,并发现OO是一种组织上的帮助-与浏览松散组织的子例程列表相比,查找功能要容易得多。
对于我OO是一个很大的好处,但是如果您不以相同的方式进行可视化或不执行高级体系结构,则可能毫无意义且令人讨厌。
评论
+1我的感觉也一样,但是有很多相反的方向,包括Ruby mixins ...这使您意识到严格的OO并不适合所有人。
–丹·罗森斯塔克(Dan Rosenstark)
2010-11-2 23:42
@Yar Yep,这几乎就是我所说的。尽管我个人无法想像任何更好的东西(在我使用Ruby的那一年,Ruby驱使我成为NUTS),但我开始接受每个人都有不同的看法。也许有些人在思考时会使用触摸或听觉,而不是视觉化,而OO并不会帮助他们。
– Bill K
2010-11-2 23:46
我认为这也有助于鼓励更自然的命名约定。您不再需要将函数的类型编码为函数名称(如INSTR)-因为名称已附加到该类型(如string :: find)
–肯·布鲁姆
2010年11月3日,19:31
@Ken尽管我同意,但我认为这比面向对象要强得多-Ruby有OO,但是由于鸭子输入会丢失很多类型信息-Ruby往往只说“发送(发送)”并期望您会知道必须使用哪种魔术方法才能起作用。
– Bill K
2010年11月4日17:38
@比尔,你是对的。支持通用编程的语言更多。您可以通过Haskell的模块和类型类系统获得不错的自然命名约定,而Haskell则没有面向对象。如果C重载,则可以在C中获得相同种类的通用名称。
–肯·布鲁姆
2010年11月4日在18:01
#12 楼
在介绍给OO之前,我已经做了相当多的GW-Basic和Turbo Pascal编程,所以最初它是DID负责的事情。不知道这是否会对别人产生影响,但对我来说就像这样:我对编程的思考过程纯粹是程序性的。如:“发生某事,然后发生某事”,等等。我从不认为变量和数据只是程序流程中短暂的参与者。编程是“行动的流程”。
我认为不容易掌握(就像现在看来对我来说很愚蠢)的想法是,数据/变量实际上真正重要。比在节目“流程”中只是转瞬即逝的演员更深刻的意义。或换种说法:我一直试图通过发生的事情而不是通过什么来理解它,这是掌握它的真正关键。
评论
有趣的观点。当我努力理解一个庞大的C ++项目时,我想相反,主要考虑数据,即从某个“输入”到某个“输出”的位的“信号路径”。虽然我也做了很多Basic和Pascal,但我最早的技术思想是电子学。
– DarenW
2010年11月12日19:43
#13 楼
我认为这并不难理解,但是可能很多程序员对这个概念感到陌生,它们来自过程语言。从我所见/读到的很多人看来(至少在论坛中)从OOP寻找“结果”。如果您是不回头修改程序代码的过程程序员,那么可能很难理解它的好处。
此外,如果人们不满意,那么那里会有很多糟糕的OOP。阅读/看到这样就很容易理解为什么他们可能会感到困难。
IMO,您需要等到它“单击”或由真正有知识的人教给我,我才认为您会赶。
评论
如果您来自学术环境,那么您在OOP中编写的玩具程序的类型似乎也毫无意义。我从大学开始学习C语言,这很容易掌握,因为每个程序只有1页,少于100行。然后,您尝试学习OOP,并且这需要对象的所有这些负担和开销才能完成同一件事,这似乎毫无意义。但是,除非您编写了一个包含许多文件和数千行的程序,否则很难理解为什么任何编程风格都很有用。
– CodexArcanum
2010年11月1日在14:07
#14 楼
我认为许多人都难以理解OOP的原因是因为这些工具并不能真正促进它。当今的计算机语言是计算机中正在发生的事情的抽象。
OOP是一种表示抽象的抽象方法。
因此,我们正在使用抽象来构建具有抽象的抽象。除此之外,我们提取的内容通常是非常复杂的物理/社交交互,而且,难怪。
#15 楼
我实际上有一个名为“面向对象编程的斗争”的博客,它源于我在学习它方面的一些挣扎。我认为我很难理解,因为我花了很多时间使用过程编程,而且我很难理解这个想法,即对象可以由一组属性和行为表示(我习惯于只是变量和方法的集合)。另外,有许多使语言面向对象的概念-继承,接口,多态性,组成等。在实际编写代码之前,确实有很多知识要学习。有效地并且以面向对象的方式,而使用过程编程,这仅仅是了解诸如变量的内存分配以及对其他方法的入口点调用之类的问题。
评论
同意-面向对象的人们面临的很多困难是他们已经训练自己能够“循序渐进地”思考。 OO并没有本质上的困难,但是如果您“了解”过程技术,那么看到另一种构造事物的方法将是非常令人惊讶的。
–柯克·布罗德赫斯特(Kirk Broadhurst)
2011年2月7日下午5:36
毫无疑问,这是与过程编程完全不同的思维方式。但是,与许多人说的相反,这不是A)一种不自然的思维方式,并且B)并不复杂。我只是认为这不好教。
–annoying_squid
2014年7月22日在20:29
#16 楼
动机。当您不了解原因以及当您无法看清所做的事情并弄清自己是否做对了时,很难学习一些东西。需要的是使用OO做有用的事情。我建议浏览一本有关设计模式的书,并提出一本显然有用并且与OO兼容的书。 (我曾经尝试过使用Strategy。像Flyweight或Singleton之类的东西会是错误的选择,因为它们通常是使用对象的方式,而不是使用对象来完成任务。)
评论
人们总是在谈论辛格尔顿,但后来他总是被邀请参加聚会。但这是真的,他是非OO OO DP。
–丹·罗森斯塔克(Dan Rosenstark)
2010年11月2日,23:45
#17 楼
我认为这取决于年龄(年龄代表经验),更重要的是兴趣。如果您“年轻”(例如,绿色),并且从未想过其他任何方法,那么这似乎很简单。另一方面,如果您认为这是您所见过的最酷的东西-28岁时在我身上发生的事情-很容易gr。另一方面,如果您认为,就像我的许多Java学生所做的那样,“我们为什么要学习它,这只是一时的风尚”,几乎是不可能学习的。大多数技术都是如此。
评论
OO流行吗?您的学生几岁-我怀疑这个“时尚”比他们大(我做的第一个对象-我知道我做的-大约在1983/4年是Simula,那时Simula还不算新)
–墨菲
2010年11月1日在15:28
@Murph大约在2004-2005年,学生肯定超过45-50岁(伊比利亚的专业程序员)。
–丹·罗森斯塔克(Dan Rosenstark)
2010-11-1 20:10
好的,我可以看一下他们是如何错过OO事情的开始的。但是到2004/5为止,我们已经很好地进入了.NET,它几乎是面向对象的(-:有些东西在开发中可能会被描述为一种时尚,但是那些没有迅速消失的东西往往会演变成好东西。
–墨菲
2010年11月2日,9:46
@Murph说实话,这些家伙是他们试图转换为Java的大型机程序员。这实际上是一种有趣而独特的体验(在我的Java Trainer时代不是正常的票价)。但是,确实,他们看到了很多事情来去去去,但是显然,OO不仅仅是一时的流行。单独说明一下:我有点希望这种单元测试的东西能够流行起来,但是现在我发现我要编写很多单元测试... :)
–丹·罗森斯塔克(Dan Rosenstark)
2010-11-2 23:36
#18 楼
不管选择哪种范例(OOP,功能等),要编写计算机程序,都需要知道程序将执行哪些步骤。定义过程的自然方法是编写降低其步骤,对于较大的任务,可以将任务分解为较小的步骤。这是程序性的方式,这是计算机的工作方式,这是您逐步检查清单的方式。
OOP是另一种思维方式。不用考虑需要逐步完成的任务清单,而是考虑对象,对象的能力和关系。因此,您将编写许多对象,小的方法,并且程序将神奇地工作。要实现这一目标,您需要改变主意...
,这就是为什么OOP很难实现的原因。由于所有事物都是一个对象,所以他们要做的就是要求其他对象做某事,而这些其他对象基本上就是做某事。因此,OOP程序中的控件可以在对象之间疯狂地来回跳转。
#19 楼
作为目前正在学习编程并且在这一领域有一些问题的人,我认为这个概念的具体实现并不难理解。我之所以这样说,是因为我有了OOP的想法,并且已经在PHP中使用了大约一年,但是当我转向C#并查看其他程序员对对象的用法时,我发现很多人这样做的方式我只是不明白。正是由于这一点,我才得以更好地理解OOP的原理。当然,我意识到这个问题很可能是我缺乏原生OOP的经验语言,随着时间的流逝,我将发现利用对象的新方法,这些新对象对于新程序员来说就像我目前所经历的一样不清楚。杰里·科芬(Jerry Coffin)谈到了这几次,特别是在他的评论中:
一方面告诉您
OOP的一大优势在于建模,这尤其成问题更接近现实,但您首先要从看起来像LSD灵感的现实世界开始,
甚至是现实中最基本,最明显的部分。
我发现这很准确,因为当我看到某人为不是真的东西创建类时,我经常会得到这样的印象-一个具体的例子使我无所适从,但是我能即时想到的最接近的例子是距离就像物体一样(下次看到会引起同样混乱的东西时,我将进行编辑)。有时,OOP似乎暂时不理会自己的规则,变得不那么直观。当对象生成对象,从封装它们的类继承等时,这种情况经常发生。
我认为对于像我这样的人,将对象的概念视为具有多个方面会有所帮助,其中之一包括在某些情况下不会像对待对象一样对待对象。诸如距离之类的东西,仅在范式上稍有变化,就可以作为一个理论对象遇到,但是却不能握在手中。我必须认为它具有一组属性,但是具有一组更为抽象的行为,例如访问其属性。我不是很确定这是我理解的关键,但似乎是我目前的研究处于领先地位。
评论
一对点或对象应视为一个对象。并且距离应作为与物体的函数。使用对象并不意味着您可以从所有对象中创建对象。
–绞肉
2014年7月28日在13:54
正如我所说,距离是一个糟糕的例子。至于用万物制造物体,我指的是我所看到的正在发生的事情,而不是我实际上所做的事情-到目前为止还没有。
–dsimer
2014年7月28日14:44
这取决于语言-在SmallTalk中,距离(以及所有东西)是一个对象。但是在C#中,您提到过这将是不好的。
–绞肉
2014年7月28日在14:54
#20 楼
在学习面向对象编程(POOP)的原理时,术语是我前进的道路。当您掌握了基本原理后,这些东西才开始逐渐成熟。就像学习新概念的所有事情都有些困难。同意设计模式应至少与OOP平行。
#21 楼
对我而言,主要的跃迁只是了解OOP的抽象概念。现在我对编程非常陌生,现在我已经进行了一年半的编程,所以我对OOP的介绍是使用Actionscript和Processing。当我第一次学习Actionscript编码时,它不在OOP中。我学会了直接在“动作”面板中进行编码,这就是我学习编程的基本原理(变量,函数,循环等)的方式。因此,我了解到它是直接在Flash或Processing中为舞台做些事情。当OOP出现时,我一开始就很难意识到自己可以在对象内创建方法和属性以进行使用和重用。一切都非常抽象并且难以处理,但是编程语言本身要好得多,但是首先建立这些连接需要一种信念的飞跃。
评论
哇,那部分没有任何意义。 “一切都非常抽象,很难在类和对象实例之间进行处理。但是,一旦获得OOP,编程语言就变得更容易理解。但是,起初建立这些连接有点费力。”
–科比
2010年11月2日,18:28
#22 楼
食谱良好的OOP理解=良好的导师或书籍或两者兼而有之+个人兴趣+练习。
个人兴趣
根据我的个人经验,借助导师或好书或两者的正确输入,从过程编程到OOP的桥梁很重要。
实践,实践和实践
更好地了解OOP的朋友不过是练习而已。这肯定会提高您的OOP能力。
俗话说:“没有什么可以代替辛勤工作,没有成功的捷径。”
祝你好运!
评论
我反对:这并不难理解,只是很难掌握。这样整体编程。嗯,不是吗?也许无法编写程序的程序员发现很难责怪他们而不是他们的代码行?我不知道,但我从未听过有人说它很难理解。但是我看到ppl说函数性很奇怪,特别是因为它们不能更改其变量的值。
@ acidzombie42:功能一点也不奇怪。您不必编写命令列表即可更改表示RAM中某个位置的变量的内容。变量代表值,您不更改值; 42停留42,x停留x –无论x是多少。您可以编写从其参数映射到结果的函数。值包括:数字,值列表,从值到值的函数,产生副作用的程序以及在执行时产生的值等。这样,主函数的结果将由编译器计算,即可以执行的程序。
我最近一直在学习Haskell。我对函数式编程的了解和了解的越多,我就越觉得OOP很难。我认为这样做的主要原因是OOP试图将数据(对象/类)与对其进行操作的功能(方法)联系在一起。这是问题的根源,因此设计了许多OOP设计模式来避免将数据和功能捆绑在一起。例如,工厂模式用于将构造函数(它是一个函数)与其在其上操作的实际对象分开。
因为它的名字不正确。它实际上应该是面向主题的编程,因为主题执行动作(动词),而对象接收动作-约翰把球扔了。所以johnsBall.throw()真的没有道理。