什么是抽象?[关闭]


38

对于程序员所使用的编程抽象,是否存在公认的定义?[请注意,不要将编程抽象与“抽象”一词的字典定义混淆。]是否存在明确的甚至是数学的定义?有哪些清晰的抽象示例?


..并在发布此消息时被迫证明我不是机器人,这表明我真的要求太多:)
mlvljr 2010年

8
“数学上”是什么意思?我真的不会将抽象视为数学概念。
Fishtoaster

2
@mlvljr:对不起,我仍然不确定我是否会遵循。抽象只是提供一种更简单的处理方式的实践。我看不到正式的工具/方法与它有什么关系。
Fishtoaster

1
@mlvljr,您是否想要一个数学示例,或者一个数学涵盖所有编程提取内容。我认为后者不存在。
C. Ross,2010年

8
Perhpas cstheory.stackexchange.com是此问题的正确
答案

Answers:


46

答案是“您可以在数学上定义编程抽象或多或少吗?” 没有。” 抽象不是数学概念。这就像要求某人用数学解释柠檬的颜色。

但是,如果您想要一个好的定义:抽象是从特定思想转变为更笼统的思想的过程。例如,看看您的鼠标。无线吗?它有什么样的传感器?多少个按钮?符合人体工程学吗?它有多大?所有这些问题的答案都可以准确地描述您的鼠标,但是无论答案是什么,它仍然是鼠标,因为它是带有按钮的定点设备。这就是鼠标的全部条件。“ Silver Logitech MX518”是一个具体的具体项目,“鼠标”是该项目的抽象。要考虑的重要一点是,没有像“鼠标”这样的具体对象,这只是一个想法。桌上的鼠标总是更具体-

您可以根据需要分层抽象和任意细化(MX518是鼠标,这是一个指针对象,这是一个计算机外围设备,这是一个用电供电的对象),可以随意扩展,并且几乎在任何方向上都可以使用(我的鼠标有一根导线,这意味着我可以将其归类为带有导线的对象。它也平放在底部,因此我可以将其归类为一种在滚动时不会滚动的对象垂直放置在倾斜的平面上)。

面向对象的编程建立在抽象,抽象或抽象组的概念上。好的OOP意味着在适当的细节级别上选择好的抽象,这些抽象在您的程序域中有意义,并且不会“泄漏”。前者意味着将鼠标分类为不会在倾斜平面上滚动的对象对于库存计算机设备的应用程序没有任何意义,但对物理模拟器而言却有意义。后者意味着您应避免将“装箱”到对于某种对象没有意义的层次结构中。例如,在上面的层次结构中,我们确定所有电脑外围设备是用电供电的吗?手写笔呢?如果要将触控笔归为“外围设备”类别,则会遇到问题,因为它不使用电能,并且我们将计算机外围设备定义为使用电能的对象。的圆椭圆问题是这一难题的最有名的例子。


2
我想我明白了;您正在专门讨论以抽象方式引用方法或函数,即通过其合同而非其实现。您的陈述是正确的,这是该术语的完全正确使用;方法调用是某种具体行为的抽象。
nlawalker 2010年

4
@nlawalker:您正在将抽象与泛化混合在一起。他们不是一回事。您要描述的是后者(“从特定的想法转变为更普遍的想法”)。抽象正在从具体事物转变为抽象事物,例如拥有7个蓝色和7个红色大理石,并说“我有两套相同数量的相同颜色的大理石”:在这里,我正在从具体事物(大理石)转向抽象事物(类和等效集)。顺便说一句,自然数n是基数n的所有等效集合的类,基数n由这些集合之间的一对一映射定义为非圆形。
pillmuncher 2010年

33
数学上,柠檬的颜色是波长约为570 nm的光。
Erik 2010年

1
@Erik我正要写那个。呸!
加里·罗

1
@Erik那是物理,不是数学:)数学对诸如“光”之类的概念一无所知。光是经验性的;数学不是。
Andres F.

25

我完全不同意大多数答案。

这是我的答案:

给定两个集合G和H,可以在它们之间定义Galois连接(alpha,beta),可以说一个是另一个的具体化。反向连接,一个是另一个的抽象。这些函数是具体化函数和抽象函数。

这是基于计算机程序抽象解释的理论,该理论通常是迄今为止的静态分析方法。


8
好吧,您会获得教授

@迈克:是吗?:-)
Paul Nathan

嗯,有没有例子?
mlvljr,2010年

2
@mlvljr:di.ens.fr/~cousot/AI astree.ens.fr提供了数据草图。
保罗·内森

1
阿米尔:这是静态分析世界中抽象的技术定义。
保罗·内森

13

抽象更多地关注What而不是更多How。或者您可以说,只知道您需要做的事情,并且仅信任提供者提供的所有其他服务。有时甚至会隐藏服务提供商的身份。

例如,此站点提供了一个用于提问和回答的系统。这里几乎每个人都知道本网站进行询问,回答,投票和其他操作的程序。但是很少有人知道什么是底层技术。就像该站点是使用ASP.net mvc还是Python开发的一样,它是否运行在Windows或Linux服务器等上,因为这与我们无关。因此,该站点在其底层机制上为我们提供服务保留了一个抽象层。

其他一些例子:

  • 汽车隐藏了所有机械装置,但提供了一种驱动,加油并将其维护的方法。

  • 任何API都会隐藏其所有实现细节,从而向其他程序员提供服务。

  • OOP中的一个类隐藏其私有成员,并隐藏公共成员的实现,以提供呼叫公共成员的服务。

  • 在Java或C ++ 中使用Interface或类型的对象时abstract class,实际的实现是隐藏的。不仅被隐藏,Interface在各种已实现/继承的类中,中声明的方法的实现也可能会有所不同。但是,当您获得相同的服务时,只需不必理会How它的实现情况,而正是Who/ What正在提供该服务。

  • 隐藏身份信息:表示“我知道Sam可以编写计算机程序”。抽象可以是“ Sam是一名程序员。程序员知道如何编写计算机程序。” 在第二句话中,人并不重要。但是他的编程能力很重要。


那么,为什么不将其称为“什么的确切说明”呢?
mlvljr,2010年


@mlvljr一点点How有助于理解Whats。因此,它可以与抽象混合。
Gulshan

7

编程抽象是问题的简化模型

例如,TCP / IP连接是对发送数据的抽象。您只需提供一个IP地址和一个端口号,然后将其发送给API。您不必担心接线,信号,消息格式和故障的所有详细信息。


啊哈!什么是简化模型?还记得漏水的谜题吗?:)
mlvljr

7

抽象只是定理的编程版本。

您有一个正式的系统,并提出了关于该系统的想法。您对此进行证明,如果可以解决,那么您就有一个定理。知道您的定理成立后,您便可以将其用于有关系统的进一步证明。系统提供的基元(例如if语句和int值类型)通常被视为公理,尽管严格来说并非如此,因为不是用计算机代码编写的CPU指令的任何事物都是一种抽象。

在函数式程序设计中,将程序作为数学语句的想法非常强烈,并且通常可以使用类型系统(以诸如Haskell,F#或OCAML之类的强大的静态类型语言)通过证明来测试定理。

例如:假设我们将加法和相等检查作为原始操作,将整数和布尔值作为原始数据类型。这些是我们的公理。因此,我们可以说这1 + 3 == 2 + 2是一个定理,然后使用加法,整数和等式的规则来确定这是否是对的陈述。

现在让我们假设我们想要乘法,并且我们的原语(为简便起见)包括循环构造和分配符号引用的方法。我们可以建议

ref x (*) y := loop y times {x +}) 0

我要假装证明了这一点,证明了乘法是成立的。现在,我可以使用乘法对系统(编程语言)进行更多处理。

我还可以检查我的类型系统。(*)的类型为int-> int-> int。它需要2个整数并输出一个整数。加法的类型为int-> int-> int,因此只要(rest)产生一个int,0 +(rest)成立。我的循环可能会做各种各样的事情,但是我说它输出的是一系列咖喱函数,结果就是(x +(x +(x ... + 0)))。该加法链的形式是(int->(int->(int ...-> int))),所以我知道我的最终输出将是一个int。因此,我的类型系统支撑了我另一个证明的结果!

多年来,许多程序员和许多代码行使这种想法复杂化,您拥有了现代的编程语言:丰富的原语集和庞大的“经过验证的”代码抽象库。



4

从数学上来说,“整数”是一个抽象。当您对所有整数进行形式为x + y = y + x的形式证明时,您正在使用抽象“整数”而不是特定的数字(如3或4)。当您与机器位于寄存器和存储器位置之上的级别。在大多数情况下,您可以在更抽象的层次上思考更强大的思想。


会不会IInt add(IInt a, IInt b);在您事先知道的程序中使用和子例程,a或者b会成为Int128: IInt一个或多或少的好例子?-即您让您的代码段执行了应该做的事情,知道(能够证明)它将完成您需要的事情,同时(另一方面)使您可以使其完全完成您要做的事情是否需要在不知道的情况下(也可以在其他环境中使用该功能)?
mlvljr 2010年

1
抱歉,我不明白你的问题。
凯特·格雷戈里

好吧,假设您正在编写一个必须将2加3的程序。您可以通过调用add(int, int)子例程/函数来实现。仅return 2 + 3;在这种情况下拥有它就足够了。以及为什么要使用更“通用”的例程(return a + b;即对提供的任何实际 参数ab参数进行操作,从而真正从其值中抽象出来),这是我上面的(修辞性)问题。希望现在变得更加清晰了。
mlvljr 2010年

我的第一个评论是“自我混淆”,我同意:)
mlvljr

4

您在这里得到了很好的答案。我只警告您-人们认为抽象是某种奇妙的东西,需要放在基座上,而您可能还不够。它不是。这只是常识。它只是识别事物之间的相似性,因此您可以将问题解决方案应用于一系列问题。

请允许我

在我的烦恼列表中,最重要的是人们谈论“抽象层”时,好像这是一件好事。他们围绕他们不喜欢的类或例程创建“包装器”,并称其为“更抽象”,似乎会使它们变得更好。还记得《公主与豌豆》的寓言吗?公主是如此的娇柔,以至于如果她的床垫下面有豌豆,她将无法入睡,而增加更多的床垫也无济于事。添加更多“抽象”层会有所帮助的想法就是这样-通常不会。这仅意味着对基本实体的任何更改都必须通过多层代码来体现。


将抽象视为“太漂亮而无法清晰地感知(或什至用干(数学)术语描述)”的想法,无助于(首先,至少)理解其本质,(其次)发展其技术。应用程序和(令人恐惧的!)评估(给定代码的抽象方式和方式)
mlvljr 2010年

3
如果一个地方的更改使您不得不在其他地方进行多个更改,那么您的抽象是不好的。从本质上讲,我不会说我或任何其他人从来没有犯过太多抽象的错误,但是有一种解决这种疯狂的方法。好的抽象是松耦合代码的基石。有了正确的抽象,更改就变得非常简单。因此,是的,我确实将抽象放在了基座上,并且花费了过多的时间来寻找合适的基座。
杰森·贝克

@Jason Baker让我们的抽象技术足够具体有效地使用...
mlvljr 2010年

1
@Jason:“如果一个地方的更改使您不得不在其他地方进行多个更改,那么您的抽象是不好的。” 我和你在一起。我似乎被坏人包围。
Mike Dunlavey,2010年

1
听起来您在开发人员抱有远见的地方工作,并且没有一个强大的老板来保持团队的专注。当我发现自己处于这样的环境中时,我开始寻找另一份工作(项目预算总是用完了,或者公司规模很小=>破产了)。我最近看到一条推文:“意大利面代码”与“意大利面条代码”,后者是在层数过多时。
yzorg 2010年

4

我认为您可能会发现有关泄漏抽象的博客文章很有用。相关背景如下:

抽象是一种机制,可以帮助利用一组相关程序片段之间的共同点,消除它们之间的差异,并使程序员能够直接使用代表该抽象概念的构造进行工作。这个新构造(实际上)总是具有参数化:一种自定义构造使用方式以适应您的特定需求的方法。

例如,一个List类可以抽象出一个链表实现的细节-在这里,您无需考虑操纵nextprevious指针,而可以考虑在序列中添加或删除值的级别。抽象是从更少的一组更原始的概念中创建有用,丰富,有时甚至复杂的功能的基本工具。

抽象与封装和模块化有关,而这些概念经常被误解。

在该List示例中,封装可用于隐藏链接列表的实现细节。例如,在面向对象的语言中,您可以将nextprevious指针设为私有,其中仅允许List实现访问这些字段。

封装不足以进行抽象,因为它不一定意味着您对结构有新的或不同的概念。如果所有List类都给了您' getNext'/' setNext'样式访问器方法,它将从实现细节中封装您(例如,您是否将字段命名为' prev'或' previous'?它的静态类型是什么?),但是它将会具有非常低的抽象度。

模块化信息隐藏有关:在接口中指定了稳定的属性,并且模块实现了该接口,并将所有实现细节保留在模块内。模块化可帮助程序员应对变化,因为其他模块仅依赖于稳定的接口。

封装可以帮助信息隐藏(这样,您的代码就不必依赖不稳定的实现细节了),但是对于模块化而言,封装不是必需的。例如,可以实现一个List用C结构,露出“ next”和“ prev”指针的世界,也提供了一个接口,包含initList()addToList()removeFromList()职能。只要遵循接口的规则,就可以保证某些属性将始终保持不变,例如确保数据结构始终处于有效状态。[例如,Parnas关于模块化的经典论文是用汇编示例编写的。该接口是合同和设计的一种交流形式,尽管我们今天依靠它,但不一定必须对其进行机械检查。]

尽管将抽象,模块化和封装之类的术语用作正面的设计描述,但重要的是要意识到,存在以下任何一种特性并不能自动为您提供良好的设计:

  • 如果n ^ 3算法被“很好地封装”,它的性能仍然会比改进的n log n算法差。

  • 如果某个接口适用于特定的操作系统,那么,例如,当需要将视频游戏从Windows移植到iPad时,模块化设计的优势将无法实现。

  • 如果创建的抽象暴露了太多无关紧要的细节,那么它将无法使用其自身的操作来创建新的构造:它只是同一事物的另一个名称。


好吧,这似乎是我真正想要的(在“ modular == abstract == good == you-never-estimate-it-just-struggle”视图上有一些常识/示例验证的“ rants”) ,谢谢(仍在阅读)
mlvljr 2010年

这是我即将做出的回答(对我自己的问题)的挑衅性座右铭:“当思维变弱时抽象就会泄漏”;)
mlvljr 2010年

2

好的,我想我已经知道您要问的问题:“什么是'抽象'的严格数学定义。”

如果是这样,我认为您不走运-“抽象”是软件体系结构/设计术语,据我所知没有数学上的支持(也许某个精通理论CS的人会纠正我)这里),除了“耦合”或“信息隐藏”以外,还有数学定义。


2

抽象是指当您忽略被认为无关的细节而赞成被认为相关的细节时。

抽象包括封装,信息隐藏和概括。它不包含类推,隐喻或启发式方法。

任何用于抽象概念的数学形式主义本身都是抽象,因为它必然要求将基础事物抽象为一组数学属性!态射的范畴理论概念可能最接近您要寻找的概念。

抽象不是您声明的东西,而是您要做的事情


+1,“我做抽象!” 一件T恤将是一件好事;)也感谢morphism(s)上的链接(尽管它并没有直接提及其中提到的poly -polyone;))。
mlvljr 2010年

2

作为向其他人解释的一种方式,我会从结果返回相反的方向:

计算机编程中的抽象是将某事物概括为某种程度的行为,即通常可以将多个相似的事物视为相同并进行相同的处理。

如果您想扩展它,可以添加:

有时这样做是为了实现多态行为(接口和继承),从而减少重复代码,而有时是这样做,以便将来可以用类似的解决方案替换某些东西的内部工作,而不必更改代码在抽象的容器或包装器的另一侧,希望将来可以减少返工。

除此之外,我认为您必须开始举例说明...


1

您可能要查看Bob Martin的一些指标

http://en.wikipedia.org/wiki/Software_package_metrics

就是说,我认为他的“抽象性”与您的不同。他的方法更多地是“缺乏对类的实现”的一种度量,意味着使用接口/抽象类。与主序列的不稳定性和距离可能会在您要寻找的内容中发挥更大的作用。


是的,记得那张纸。鲍勃叔叔在激励人群和使人们对OO的机制产生兴趣方面非常出色。
mlvljr,2010年

奇怪的是,我忘了投票():)
mlvljr 2010年

1

Merriam-webster将抽象定义为形容词存在:与任何特定实例无关。

抽象是某些系统的模型。它们通常列出了一组真实的系统要能够通过抽象建模所必须满足的假设,并且它们通常用于允许我们概念化日益复杂的系统。从实际系统转到抽象没有任何正式的数学方法可以这样做。这取决于谁在定义抽象,以及抽象的目的是什么。

但是,通常情况下,抽象是根据数学构造来定义的。那可能是因为它们在科学和工程学中经常使用。

一个例子是牛顿力学。它假设所有事物都无限小,并且所有能量都是守恒的。对象之间的相互作用由数学公式明确定义。现在,正如我们所知道的,宇宙并不能完全按照这种方式工作,而且在许多情况下,抽象会泄漏出去。但是在很多情况下,它都可以很好地工作。

另一个抽象模型是典型的线性电路元件,电阻器,电容器和电感器。同样,通过数学公式清楚地定义了相互作用。对于低频电路或简单的继电器驱动器等,RLC分析效果很好,并提供了很好的结果。但是在其他情况下(例如微波无线电电路),元素太大,并且交互作用也更好,并且简单的RLC抽象也无法成立。此时该做什么取决于工程师的判断。有些工程师在其他工程师的基础上又创建了另一种抽象,有些工程师用新的数学公式代替理想的运算放大器以了解其工作方式,有些工程师则用模拟的实际运算放大器代替了理想的运算放大器,而后者又是由较小的复杂网络模拟的。理想元素。

正如其他人所说,这是一个简化的模型。它是用于更好地了解复杂系统的工具。


我可能应该更好地强调这一点,但是我对那些缺乏缺乏真实世界原型细节的抽象感兴趣,但是对应该处理上述真实世界对象的系统设计提供了一些有用的提示(示例是使用一些实际的Employee属性构造Employee类,这在业务应用程序中可能会有用)。我感兴趣的是一种将软件实体与处理该实体的其他此类软件实体“隔离”的一种抽象(示例将Employer基于的假设Employee)。
mlvljr 2010年

1
你没有任何意义。提供有关设计实际系统的提示并不是抽象的目的。如果您对建模的东西一无所知,那么解决抽象问题就不成问题了。
whatsisname 2010年

我当时说的是在创建该软件的过程中,抽象出该软件将要处理的真实对象的细节。使用现实世界实体的(软件)抽象来(重新)设计那个现实世界不是什么意思(《软件系统》中的“软件系统”作为“系统”,但在“系统”中提供了一些有用的提示)我在上面的评论)。
mlvljr 2010年

1

抽象是用其他东西来表示某些东西(例如,概念,数据结构,函数)。例如,我们使用文字进行交流。单词是一个抽象实体,可以用声音(语音)或图形符号(书写)表示。抽象的关键思想是,所讨论的实体与基础表示形式有所不同,就像单词不是用来说出它的声音还是用来写出它的字母一样。

因此,至少在理论上,抽象的基础表示可以用其他表示代替。但是,实际上,抽象很少与底层表示完全不同,有时表示会“ 泄漏 ” 出去。例如,言语带有情感底蕴,很难用书面形式传达。因此,录音和相同单词的笔录可能会对观众产生很大的影响。换句话说,单词的抽象经常泄漏。

抽象通常是分层的。词是可以用字母表示的抽象,而字母本身又是声音的抽象,而声音又是声音的运动模式的抽象,该运动是由人的声带产生的,并由人的耳鼓检测到的。

在计算机科学中,位通常是最低的表示形式。字节,内存位置,汇编指令和CPU寄存器是下一个抽象级别。然后,我们获得了高级语言的原始数据类型和指令,这些数据类型和指令以字节,内存位置和汇编指令的形式实现。然后是根据原始数据类型实现并内置于语言指令中的函数和类(假定为OO语言)。然后,根据较简单的函数和类来实现更复杂的函数和类。其中一些功能和类实现数据结构,例如列表,堆栈,队列等。这些功能和类又用于表示更具体的实体,例如流程队列,员工列表或书名哈希表。


1
如果它是泄漏的,那么显然不是抽象的……足够了,说实话。
mlvljr 2010年

2
不幸的是,@ mlvljr计算机不是数学问题,因此您必须考虑一定程度的泄漏。如果没有其他要求,则实际上是在物理设备上执行计算的事实意味着对可建模问题范围的某些约束。从技术上讲,不完全性定理暗示着某些内部无法证明数学系统的事物,因此,即使数学也具有“泄漏抽象”。
CodexArcanum 2010年

2
您总是可以发现抽象将泄漏的情况。没有完美的抽象之类的东西。这仅仅是泄漏多少以及您是否可以忍受它的问题。
迪马

@CodexArcanum 1.一个例程,该例程使用int小于(MAX_INT_SIZE / 2-1)的值,并返回另一个两倍的例程:int f(int a) { return a*2; }2.一个“处理程序”,其原型void (*) (void)应在...调用者的合同-都代表抽象(1-实现细节(我们已经提供了,但是对于那些无法访问源代码的人来说是不可用的)),2--处理程序的确切含义确实(但是请注意,这对于分配处理程序的人员是已知的))并且不会泄漏
mlvljr 2010年

在方法签名中的任何地方都没有阐明对MAX_INT_SIZE的限制。除非您使用允许基于合同的编程的语言(例如Eiffel),否则是泄漏。文档中提及的限制不算在内,因为文档在系统外部。而且如果在操作过程中电源关闭怎么办?如果您必须通过网络传输数据并且存在延迟怎么办?没有编程范例可以抽象出系统硬件的物理特性。
CodexArcanum 2010年

1

我尝试向人们描述的一种方法,可能不是最好的方法

考虑一个将2 + 2相加并输出4的程序

考虑一个程序,该程序将用户输入的两个数字相加,x + y = z

哪个更有用和更通用?


这几乎就是我对Kate Gregory的回答的评论。;)有趣的是,虽然通用性较低的程序可以使用通用性较高的程序,但是向请求第一个程序的用户提供第二个程序可能会适得其反……
mlvljr 2010年

1

我认为抽象是隐藏不必要细节的东西。过程是最基本的抽象单元之一。例如,当我从文件中读取数据时,我不想担心如何将数据保存到数据库中。因此,我创建了一个save_to_database函数。

抽象也可以结合在一起以形成更大的抽象。例如,功能可以放在一个类中,类可以放在一个程序中,程序可以放在一个分布式系统中,等等。


只要/选择了所需的实现,代码调用就save_to_database不必担心数据的存储准确度!即会有提供(抽象“相对”到一些代码段)详情反正一个地方,这是明智地选择它的只是这件事-为更容易“改变主意”,等等
mlvljr

1

我一直认为编程中的抽象是隐藏细节并提供简化的界面。这是程序员可以将艰巨的任务分解为可管理的部分的主要原因。通过抽象,您可以为部分问题创建解决方案,包括所有详细的细节,然后提供一个简单的界面来使用该解决方案。然后,您实际上可以“忘记”详细信息。这很重要,因为一个人无法立即将一个超级复杂系统的所有细节都牢记在心。这并不是说抽象底层的细节永远都不需要重新讨论,而是暂时只记住接口。

在编程中,此简化接口可以是从变量(抽象一组位并提供更简单的数学接口)到函数(抽象处理量到单个行调用中)到类以及其他任何东西。

最后,程序员的主要工作是通常将所有计算细节抽象出来,并提供一个简单的界面(如GUI),一个对计算机工作原理一无所知的人可以利用。

抽象的一些优点是:

  • 允许将大问题分解为可管理的部分。当将一个人的记录添加到数据库中时,您并不需要在数据库上插入和平衡索引树而感到麻烦。这项工作可能在某个时候已经完成,但是现在已经被抽象掉了,您不必再为它担心。

  • 允许多个人一起完成一个项目。我不想知道我同事代码的所有内容。我只想知道如何使用它,做什么以及如何将其与我的作品(界面)配合使用。

  • 允许没有必要知识的人执行复杂的任务。我妈妈可以更新她的Facebook,她在全国各地认识的人都可以看到它。没有一个疯狂的复杂系统到一个简单的Web界面的抽象,她就不可能开始做类似的事情(我也不会这样做)。

但是,抽象可能会产生相反的效果,如果过度使用抽象,它会使事情变得难以管理。通过将问题分解为许多小片段,您必须记住的接口数量会增加,并且很难理解真正的情况。像大多数事物一样,必须找到平衡点。


1

间接的额外级别。

您不需要关心所使用的对象是a Cat还是a Dog,因此您可以通过虚函数表查找正确的makeNoise()函数。

我确定这也可以应用于“较低”和“较高”级别-想一想编译器查找正确指令以用于给定处理器或Haskell Monad通过调用all return和来抽象计算效果>>=


1

这实际上是我想写博客的时间更长的时间,但是我从来没有去过。幸运的是,我是代表僵尸,甚至还有赏金。我的帖子结果相当冗长,但这是本质:

编程中的抽象是关于在给定上下文中理解对象的本质的。

[...]

抽象不仅被误认为是泛化,而且还被封装所误解,但这是信息隐藏的两个正交部分:服务模块决定其愿意展示的内容,客户端模块决定其愿意看到的内容。封装是第一部分,而抽象则是后者。只有两者一起构成完整的信息隐藏。

希望能有所帮助。


+1,是的,这个话题似乎真的使我们很多人感到困惑;)我希望(最后)以我自己的观点补充您的回答,以引起对讨论的更多兴趣。
mlvljr 2010年

0

这是一个非数学的答案:

精疲力尽的编程是假装您现在不在乎细节,而实际上您确实在乎,应该一直在关心它们。基本上是假装。


1
+1,但我并不总是这样(想想真正不必要的细节:))。最初的问题是:“是永远删除细节,暂时忘记细节,还是以某种不知道的方式利用它们?”
mlvljr

1
我不在乎今天有多少光子击中了我的客户。
flamingpenguin 2010年

0

对我来说,抽象是“字面上”不存在的东西,就像是一个想法。如果您以数学方式表达它,那么它就不再是抽象的,因为数学是一种表达大脑中发生的事情的语言,因此它可以被其他人的大脑理解,因此您无法构建自己的想法,因为如果这样做,那么它就不是一个想法不再:您将需要了解大脑如何表达思想模型。

抽象是使您可以将现实解释为可以独立于现实的事物。您可以抽象一个海滩和一个梦,但是海滩存在,但梦不存在。但是您可以说两者都存在,但这不是事实。

抽象中最困难的事情是找到一种表达它的方法,以便其他人可以理解它,从而使其变为现实。那是最艰巨的工作,而且它真的不能独自完成:您必须发明一个适用于您的想法并且可以被其他人理解的相对模型。

对我来说,计算机语言中的抽象应该被称为“数学化”模型,它是关于重用可以交流的思想,与可以抽象地实现的思想相比,这是一个巨大的约束。

简而言之,原子彼此相邻,但它们不在乎。组成人类的大量分子可以理解他在某个人的旁边,但是却无法理解,这只是原子如何将自己定位成某种模式。

通常,由一个概念所统治的对象无法“理解”自身。这就是为什么我们试图信仰上帝,为什么我们很难理解我们的大脑。

我现在可以拿起勋章吗?


0

有趣的问题。我不知道抽象的单一定义在编程时被认为是权威的。尽管其他人提供了CS理论或数学各个分支的一些定义的链接;我喜欢以类似于“ supervenience”的方式来思考它,请参见http://en.wikipedia.org/wiki/Supervenience

当我们谈论编程中的抽象时,我们实质上是在比较一个系统的两个描述。您的代码是程序的描述。您的代码抽象也将是对该程序的描述,但级别更高。当然,您可以对原始抽象进行更高级别的抽象(例如,高层系统体系结构中的程序说明与详细设计中程序的说明)。

现在,是什么使一个描述比另一个描述“更高级”。关键是“多重可实现性”-您可以使用多种语言以多种方式实现对程序的抽象。现在您可能会说一个人也可以为一个程序制作多个设计-两个人可以制作两个不同的高级设计,两个设计都能准确地描述该程序。实现的等价性有所不同。

在比较程序或设计时,必须以允许您确定该级别描述的关键属性的方式进行。您可以说一个设计等同于另一个设计的复杂方法,但是最简单的思考方法是:一个二进制程序可以满足两个描述的约束吗?

那么,是什么使一个描述水平高于另一个描述水平?假设我们有一个级别的描述A(例如设计文档)和另一个级别的描述B(例如源代码)。A比B更高的水平,因为如果A1和A2是两个非等价的描述在电平A,则这些描述的实现中,B1和B2 必须也有非等效于电平B.但是,反向不一定保持为真。

因此,如果我无法生成一个满足两个不同设计文档的二进制程序(即那些设计的约束会彼此矛盾),那么实现这些设计的源代码必须是不同的。但是,另一方面,如果我采用了两组无法编译到同一二进制程序中的源代码,那么仍然可能是由于编译这两套源代码而产生的二进制文件都满足相同的设计文献。因此,设计文档是源代码的“摘要”。


0

编程抽象是某人对编程元素进行的抽象。假设您知道如何使用菜单项和菜单项构建菜单。然后,有人看到了这段代码和想法,嘿,这可能对其他种类的多层次结构有用,并定义了Component Design Pattern,它是第一段代码的抽象。

面向对象的设计模式是抽象的一个很好的例子,我并不是说真正的实现,而是我们应该采用的解决方案。

因此,总而言之,编程抽象是一种使我们能够理解问题的方法,它是获得某些东西的手段,但它并不真实。

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.