困惑。 OO本质上是必要的还是多范式的?

时间:2009-02-16 14:56:07

标签: programming-languages paradigms

正如我已经阅读了stackoverflow的答案和问题,我得到的印象是,OO被划分为本身就是必要的。

但OO只是将代码和数据划分为现实世界对象的一种方式吗?

如果是这样,为什么放弃其他较低级别的范式才能在这样的平台上运作?

IOW,默认情况下不可变的基于对象的泛型类型系统将是功能性第一语言的工作方式,默认情况下可变的基于对象的泛型类型系统将是命令式语言的世界。

或者我完全错过了什么?

7 个答案:

答案 0 :(得分:14)

即可。 OO和命令是两个正交的概念。

例如:

  • Common Lisp对象系统是Lisp OO的一个例子,可能是最复杂的对象系统。
  • OCaml是一种功能语言,具有对象系统和支持面向对象组织的模块系统
  • Scala是一种具有非常灵活的OO系统的功能语言
  • Haskell允许您使用更高级的多态性编写面向对象的代码

有很多不同的方法可以面向对象。

答案 1 :(得分:6)

大多数OO语言都是必不可少的,但可以以某种功能性的方式使用它们。一些函数式语言位于OO框架之上(F#on .NET是最明显的例子),为了在适当的时候使用大量框架而牺牲一些“纯度”。

我认为“主要是OO”语言有很多很多的空间来帮助编写功能样式 - 更好地支持不变性是最明显的特性,可能会有更好的类型推断。 (至少在谈论C#时,这可能是传统语言试图进入功能门的最重要的例子。)

答案 2 :(得分:4)

是。面向对象是一种编程风格,它允许程序员将程序表达为一组有状态的对象,这些对象的行为和交互(通常是通过动态类型的消息传递)语言和方法调用静态类型语言),并按特定顺序执行。

状态,动作和序列是来自过程式编程的概念,并且不存在于非单一函数式编程中(monad用于在纯函数式语言Haskell中实现状态,动作和序列,否则它们将没有这些概念)。

答案 3 :(得分:2)

从不同的角度来看,大多数人都喜欢强制思考(而不是在递归或RPN中)。由此可见,大多数语言都是必不可少的。

当然,使用非强制性方法(例如用户界面)表达(或解决)许多问题要简单得多,但是大多数人对这种方法并不是很满意。有些人不喜欢离开这条路,而其他人真的很难做出从这一方面处理问题所必需的心理变化(思考方法调用和递归而不是变量和循环)。

答案 4 :(得分:2)

我仍然坚信,面向对象本质上是一种必然的概念。然而,正如recent question让我更多地考虑编程范式,我总结了一个更全面的答案,这有点偏离主题,但顺便提一下也回答了你的问题:

两个主要的编程范例是声明范式,其中程序员写下抽象关系(从而告诉编译器他想要什么)和命令式范例,程序员写下算法(从而告诉计算机如何得到他想要的东西)。

范式是先验语言无关 - 它更像是一种思考和构建程序的方式。但是,语言使用范式的容易程度存在差异:语言语义和语法导致编写代码的惯用方式。

声明性语言的一个例子是Prolog,命令式语言的一个例子是Fortran( Real Programmer可以用任何语言编写FORTRAN程序)。

作为同时具有命令性和声明性的代码的示例,请考虑Perl6中Fibonnaci序列的这种实现:

my @fibonacci-sequence := 0, 1, * + * ... *;

这显然是序列的声明性描述。但是,由于*...是有效的Perl6运算符 - 可以使用任何星形来创建lambda表达式,用于创建惰性列表的序列运算符 - 它也是调用运行时内在函数的命令式语句代码。

让我们考虑一些其他编程范例,特别是功能和面向对象的编程。

功能范例本质上是声明性的,因为它将计算模型化为集合之间的关系。

面向对象的范例本身就是必不可少的,因为它将计算建模为有状态对象之间的通信,称为消息传递。

有些语言是纯粹的,这意味着所有计算都符合范式。例如,Haskell是一种纯函数式语言,Smalltalk是一种纯粹的面向对象语言。

但是,这并不意味着功能语言可以使用。面向对象的语言可以防止命令性的resp。声明性编程。在实践中,您经常使用函数 - 您输入一个输入值来获取输出值。反过来也适用于面向对象的编程:对象接受的消息集声明了它的接口。

答案 5 :(得分:0)

有些人不同意OO是一个必要的概念,所以这是我的理由。

面向对象的要领:

  1. 对象保持状态(即对其他对象的引用)
  2. 对象接收(和处理)消息
  3. 处理消息可能会导致
    • 发送给对象本身或其他对象的消息
    • 对象状态的变化
  4. 这意味着oo编程需要对象(!)持有的可变状态。如果您通过创建一系列对象来模拟状态更改,那么您就会破坏这些不变量,就像那样简单。

    Flamebait:如果您不同意这种面向对象的定义,请与Alan Kay一起讨论。

答案 6 :(得分:0)

许多不同的概念有助于面向对象编程的概念。 Wikipedia列出了大部分内容。

我会通过使用Objects with Behaviours来描述OOP的本质。

维基百科通过以下三个属性来表征对象

  1. 标识:将其与其他对象区分开来的对象的属性
  2. 状态:描述存储在对象中的数据
  3. 行为:描述可以使用对象的对象界面中的方法
  4. 许多面向对象语言都有类的概念,但实际上,还有Prototype-based languages类似JavaScript。

    函数式语言也可以使用类(例如Haskell中的Type Classes)。但仅仅因为它们具有类并不意味着它们是面向对象的或允许面向对象的编程。继续Haskell的例子:你甚至没有对象!没有“身份”这样的概念!你所能做的只是组成纯粹的功能!

    仅仅因为有人使用了一个名为“类”的术语,这并不意味着他们正在进行面向对象的编程!

    OOP是关于具有行为的有状态对象。虽然对象的行为不必修改该对象,因为可以创建新对象,但您完全不需要对象。您不再需要Identities,因为对一个对象的更改是否被其他对同一对象的引用反映无关紧要,因为不再有任何更改。您只需要值(无标识)和模块和/或类,用于数据隐藏和封装。

    所以,命令式编程是OOP固有的。