程序性程序和面向对象程序之间有什么区别?

时间:2009-02-10 01:08:38

标签: c++ c oop procedural-programming

我对编程很新,但我一直在阅读有关各种编程方法的StackOverflow的一些有趣的讨论。我还不是100%清楚程序编程和面向对象编程之间的区别。听起来像面向对象的编程仍然使用过程(方法),但所有内容的组织方式都不同,因为对象是节目的明星。但在我看来,程序仍然允许你做所有相同的事情。与在C中一样,您可以将所有类似的过程放入库中。你真的不能说C中的库类似于C ++中的对象吗?

17 个答案:

答案 0 :(得分:33)

在程序程序中,代码为王,数据为从属。换句话说,您拥有对数据起作用的程序,而且它们通常不会紧密绑定。

在OO世界中,物体是主要感兴趣的东西。对象由数据组成,允许对该数据进行操作,并且它们的绑定非常紧密。它是封装的概念,隐藏信息。

一个例子,假设你有一个数字,你想加倍它。这样做的程序方法是:

n = n * 2

这里的代码非常明确地将n乘以2并将结果存储回n。

这样做的方法是向号码对象发送“消息”,告诉它自己加倍:

n.double();

这种优势称为多态性。当您决定要将“bob”这样的字符串加倍时会发生什么。在程序世界中,你必须提供更多的代码来进行加倍,但你还必须以不同的方式调用该代码。

使用OO,您可以创建一个字符串对象,该对象也可以采用“双重”消息。将字符串加倍的代码属于字符串对象,因此它知道它必须对数字对象采取不同的行为。如果它决定“bob”* 2是“bobbob”,代码看起来像是:

class number:                    class string:
    int n                           char array s
    procedure double:               procedure double:
        n = n * 2                       s = string_join(s,s)

然后你可以调用x.double(),无论实际的x是什么类型(数字或字符串),它都知道要运行哪些代码 - 这大大简化了你的代码。您可以在显示器上加倍整数,字符串,矩阵,复数,实数,窗口大小以及各种不同的东西。

你是对的,可以让C库看起来有点像对象。经典的例子是stdio.h - 你永远不会关心 FILE*实际指向的是什么,只是它会以某种方式表现。 FILE*fopen()fclose()和其他函数是表示C的I / O功能的一类。

答案 1 :(得分:21)

您可以在大多数OO语言中进行程序化编程,但OO的强大功能来自于继承,封装和抽象该过程逻辑的能力。 我认为你是对的,图书馆应该看起来很像一个类。它应该有自己的范围,并在具有有意义名称的函数后面封装逻辑。

答案 2 :(得分:15)

你的观察是正确的,面向对象的程序在很多方面都基于程序范式。你在语法上也是正确的,所有真正发生的事情都是你调用函数。实际上,您可以使用过程机制(例如,C ++中的函数指针)实现面向对象语言的许多功能。因此,您可以进行面向对象的设计,并仍然以过程语言实现它(例如,像旧的C ++编译器那样)。

面向对象范式的重要性在语言机制中并不像在思考和设计过程中那么重要。在程序编程中,思考是关于操作并使用其他操作将这些操作分解,将它们分组为模块等。这意味着数据或状态属于次要重要性。这就像思考数学运算一样。

另一方面,面向对象的范例表明,您需要将状态和操作一起视为一个实体,然后将程序设计为交换状态和激活操作的实体之间的交互。

答案 3 :(得分:13)

两者之间的区别很微妙但很重要。

在程序程序中,模块通过读取和写入存储在共享数据结构中的状态进行交互。

在面向对象的程序中,对象形式的模块通过向其他对象发送消息来进行交互。

答案 4 :(得分:10)

恕我直言,面向对象编程是一种概念,它存在于比程序编程更高的抽象层次。这两者并不相互排斥,因为OO程序中的各个方法看起来与程序程序中的各个函数几乎相同。这与例如功能编程形成对比,后者需要完全不同的思维模式。此外,您可以通过使所有内容静态等在OO语言中编写程序。您可以成为人工编译器,并通过使用大量函数指针和结构指针转换在C中有效地编写OO代码。

那么,OO更像是一种设计哲学和世界观,而不是具有严格定义的东西。它要求在构造代码时使用继承,多态等作为主要模式,并且提供语法以使这些语法可以在不诉诸低级技巧的情况下表达。它要求您将作为数据集合状态的代码视为数据的属性,而不是单独存在的过程。它不是黑色和白色。您的代码可以是“更多”或“更少”OO,具体取决于您依赖继承,多态,类和“作为数据属性的方法”世界观的程度,作为构建和解释/理解代码的方法。

答案 5 :(得分:8)

OO主要是心态。你可以在C中编写OO(如果你真的想...),你可以完全拥有C ++ / Java中的过程代码;我的意思是,即使你在表面使用类,它仍然可以是程序性的。

OO背后的想法是对国家的抽象。而不是“思考”“数据分组”,而是“思考”“对象”,其中对象是“数据分组和操作此数据的方法”的“接口”。

这听起来很哲学,因为它是

这里有很多话要说,并且不能在一篇小SO帖中说出来,所以我会留在这里。

<强>更新
正如Flanagan's answer中提到的,OO语言实现了利用这种抽象的构造。

我的意思是,从结构,函数和函数指针的角度来看,技术上可以“破解”类和多态。

以下是OO in C

的示例

答案 6 :(得分:6)

区别在于对象在同一个地方有程序和相关数据 - 程序语言使用'结构'(将相关数据保存在一起的东西),这使数据与程序分开。实际上,你在OO语言中所做的任何事情都应该是一种程序性语言,结合了结构和程序。

主要区别在于OO语言让程序员进入的思维模式。

答案 7 :(得分:6)

[原谅引子风格,已经晚了,我累了]

程序处理数据 - 数据输入,应用一些处理,获取数据

有时,某些数据元素与某些其他数据元素相关,将它们组合成一个数据结构很方便,然后可以将其作为一个单元进行操作和处理

现在我们的程序可以将数据结构作为输入并对其进行更改和/或生成另一个数据结构作为输出

偶尔我们会注意到某些程序只涉及某种数据结构;将这些过程与其数据结构组合在一起很方便,并将其称为对象

用于创建对象的模板称为;一个对象被称为类

实例

我们可能会注意到一个类与另一个类非常相似,所以不是复制和粘贴代码,而是让一个类从另一个类继承子类继承自< em>超类或“基类”。通过这种方式,子类可以访问超类的所有数据结构和过程,并且可以以某种方式扩充或覆盖它们

如果我们礼貌地请求一个对象为我们做某事而不是直接粗暴地调用它的过程,这就叫做消息传递,即使没有传输实际的“消息”。这里的喜悦是许多不同类型的对象可以理解相同的消息,这导致多态性的概念。例如,我们可以要求许多不同类型的文档进行打印,并且每个文档都会做出适当的响应。

支持对象(通过类或非类)与消息传递和继承的语言称为面向对象。如果没有继承,则语言仅仅是基于对象的

祝你学习顺利!

答案 8 :(得分:4)

程序是描述程序应该做什么的不同方式之间的程序/功能/逻辑(或逻辑导向)区分(比较c,lisp和prolog)的一部分。

面向对象与其他想法正交,并描述了一种用数据对子程序进行分组的方法。 C ++和java是具有面向对象特性的过程语言; fortran77是一种没有面向对象特征的过程语言。常见的lisp支持面向对象;一些较老的lisps没有。普通的vanilla prolog不支持对象,我不能命名一种逻辑导向的语言(我不做逻辑导向的编程,当我一些时,它就在我要做的事情列表中大量的业余时间。我几乎没有功能性编程。)

正如其他人所指出的那样,正确的面向对象思维会改变你编程的方式,就像从程序转换到功能一样。


BTW--我看到“程序性”用于区分非面向对象的程序语言和面向对象的兄弟,但我认为这是由于缺乏一个干净的形容词而导致的不良用法为本”。 YMMV。

答案 9 :(得分:2)

区别在于

面向过程的编程 - 重视算法而不是数据。这种编程方式集中在程序上,即执行特定任务和共享数据结构的方法。它遵循自上而下的结构。

示例:Pascal和C

面向对象编程 - 重视数据而不是算法。它遵循自下而上的结构。每件事都被视为一个对象。每个对象都有自己的数据结构和过程。它包括数据隐藏,多态,封装和消息传递等功能。用户真的不必在这些对象中使​​用它们,而在程序中使用它们。

示例:C ++和Java

答案 10 :(得分:2)

在程序性程序中,您将一个大问题划分为小问题,并将这些小问题中的每一个抽象为一个过程。这称为程序抽象。

在面向对象的程序中,您将问题分析为某些对象以及对象之间的交互。这称为对象抽象。

答案 11 :(得分:2)

在上下文中更容易理解,看看语言之间引入的其他抽象。

汇编语言和C或Pascal等过程语言之间的关键区别在于引入了“过程”抽象。编写汇编代码的人创建了程序,但它容易出错并且容易出错,程序语言为您提供了使工具更容易的工具。

过程语言和像C ++这样的OO语言之间的区别在于“对象”抽象。编写“c”的人经常创建概念对象but its difficult and error prone,OO语言为您提供了使其更容易的工具。

来自Microsoft(或Erlang)的Sing#之类的东西将Message / Process抽象添加到语言中。当然,您可以在汇编,C或C ++中进行消息传递和进程创建,但Sing#使其更容易。

这一切都归结为相同的机器代码,这些抽象纯粹是为了我们的大脑,而不是计算机。

答案 12 :(得分:1)

这取决于您如何定义OOP。就类似Java的OOP而言,在对象上调用方法时,过程编程几乎是一样的。据我所知,你可以在像C这样的过程语言中模拟所有OOP原则(封装,抽象,多态,继承)。证明这是GObject,某些扩展Objective-C,以及许多其他OOP语言使用C的实现,如cPython。这是通过使用结构并使用函数对这些结构进行操作来完成的:

typedef struct {
    Object *isa;
    String *name;
    Date *birthday;
} Person;

Person *Person_new();
String *Person_name(Person *self);
void Person_setName(Person *self, String *newName);
// ...

界面很像OOP。它并不真正允许多态,但它也是可能的。它与Python接口非常相似,只是属性与“方法”分开:

class Person(object):
    def __init__(self):
        self._name = ""
        self._age = datetime.datetime.now()

    @property
    def name(self):
        return self._name

    @property
    def age(self):
        return self._age

我选择Python作为示例,因为“self”是显式的,如C示例中所示。许多OOP语言,如Java,都是抽象的。

还有类似Smalltalk的OOP,其中消息被发送到对象,而不是调用对象上的方法。乍一看差异很微妙,但它提供了很大的力量和灵活性。这也可以用过程语言实现,如Objective-C所证实的那样。

面向对象编程不一定是一种语言,而是一种范式。面向对象的语言,如Java,Python,Ruby等,提供了易于操作对象的语法糖,这是“过程语言”和“面向对象语言”之间的主要区别。

实际上,库,或者说是在结构上运行的一组函数,与C ++中的对象相同。事实上,C ++就是以这种方式实现的。

答案 13 :(得分:1)

这是一个简化的答案。

  • 在真正的OO语言中,唯一的过程编码是在对象内部完成的。

  • C没有对象,C ++是支持对象的语言。另一方面,Java一切都是对象(原语除外)。一切都是打字的。

  • 线性进展发生在对象内部,但对象本身只是代码和数据的集合。

答案 14 :(得分:0)

对于程序性和面向对象之间差异的一个相当面对面的例子,尝试学习Smalltalk。在Smalltalk,一切,我的意思是一切都是一个对象。没有if语句或while循环。您可以通过向其他对象发送(a.k.a。调用方法)消息来实现该功能。它真的让你的头开始旋转,但我想你会很快弄清楚OO应该是什么。

答案 15 :(得分:0)

实现C ++的方式只是使OO编程看起来很像程序编程。你需要稍微改变一下你的想法。

在C ++对象中,方法只是作用于对象的过程。但是在真正的OO paradiam中,你应该把这些方法看作是对象可以接收的潜在消息(即字母)。对象接收消息(参数表示消息的有效负载,即字母的内容),并根据消息更改其状态。

答案 16 :(得分:0)

这里已经提到过很多有趣的观点。

考虑它的一种方法是,在OO中,你有“对象”的概念,这些对象具有它们固有的特征和行为。它们通常具有某种公共“界面”,它提供了一种机制来检索有关它们的一些信息,但是对象本身,或者更确切地说是它的“类”,限制了公开可用的信息。对象的内部不会暴露给公众,因为通常不需要知道对象的“引擎盖下”的脏细节。所以面向对象的程序利用了这个结构以及其他东西。

程序编程通常不会将数据和行为的这种耦合用于“对象”。我之前已经看过它在C语言中完成但它不是很漂亮,并且涉及太多的猴子业务来近似用C ++来做什么。

面向对象开发背后的一个想法是,我不应该通过除你提供的方式以外的任何方式来处理数据。如果你只提供一个经过深思熟虑的界面,你可以保持诚实。现在,如果你正在使用程序方法而且你发给我一个没有内置保护的结构,那么我可以随心所欲地做,如果我是愚蠢或邪恶,我可以改变你可能不想要我的东西更改。

当然,如果你聪明,你就可以规避对象,但是你必须不再这样做。

这不完整,但这是一个方面。