当我通读 stackoverflow 的答案和问题时,我得到的印象是 OO 被划分为本质上是必要的。
但是,OO 不只是一种将代码和数据划分为现实世界对象的方法吗?
如果是这样,为什么要放弃其他较低级别的范例来在这样的平台上工作?
IOW,默认情况下不可变的基于对象的泛型类型系统将是功能性第一语言的工作方式,默认情况下可变的基于对象的泛型类型系统将是命令式语言的世界。
还是我完全错过了什么?
当我通读 stackoverflow 的答案和问题时,我得到的印象是 OO 被划分为本质上是必要的。
但是,OO 不只是一种将代码和数据划分为现实世界对象的方法吗?
如果是这样,为什么要放弃其他较低级别的范例来在这样的平台上工作?
IOW,默认情况下不可变的基于对象的泛型类型系统将是功能性第一语言的工作方式,默认情况下可变的基于对象的泛型类型系统将是命令式语言的世界。
还是我完全错过了什么?
没有。OO 和命令式是两个正交的概念。
例如:
面向对象有很多不同的方法。
大多数 OO 语言都是命令式的,但您可以以某种函数式风格使用它们。一些函数式语言位于 OO 框架之上(.NET 上的 F# 是最明显的例子)权衡一些“纯度”,以便在适当的情况下使用一个庞大的框架。
我认为“主要是面向对象”的语言还有很大的空间可以做更多的事情来帮助以函数式编程方式进行编程——更好地支持不变性是最明显的特性,可能其次是更好的类型推断。(至少在谈到 C# 时,这可能是传统语言试图涉足函数式大门的最重要的例子。)
是的。面向对象是一种编程风格,它允许程序员将程序表示为一组有状态的对象,这些对象进行操作和交互(通常通过动态类型语言中的消息传递和静态类型语言中的方法调用),并以特定的顺序进行。
状态、动作和序列是过程编程中的概念,在非单子函数式编程中不存在(单子用于在纯函数式语言 Haskell 中实现状态、动作和序列,否则不会有这些概念)。
从不同的角度来看,大多数人喜欢命令式思考(而不是递归或 RPN)。由此可见,大多数语言都是命令式的。
当然,使用非命令式方法(例如用户界面)来表达(或解决)许多问题要简单得多,但大多数人对这种方法并不感到满意。有些人不喜欢离开人迹罕至的道路,而另一些人则确实很难进行必要的心理改变以从这方面解决问题(考虑方法调用和递归而不是变量和循环)。
我仍然坚信面向对象本质上是一个必要的概念。但是,由于 最近的一个问题让我对编程范式进行了更多思考,所以我整理了一个更全面的答案,这有点离题,但顺便也回答了你的问题:
两种主要的编程范式是声明范式,程序员写下抽象关系(从而告诉编译器他想要什么)和命令式范式,程序员写下算法(从而告诉计算机如何得到他想要的东西) .
范式与先验的语言无关——它更多地是关于您如何思考和构建程序的一种方式。但是,一种语言使用范式的容易程度存在差异:语言语义和语法导致了一种惯用的代码编写方式。
声明性语言的一个例子是 Prolog,命令式语言的一个例子是 Fortran(Real Programmer 可以用任何语言编写 FORTRAN 程序)。
作为同时具有命令性和声明性的代码示例,请考虑 Perl6 中斐波那契序列的以下实现:
my @fibonacci-sequence := 0, 1, * + * ... *;
这显然是对序列的声明性描述。然而,作为*
有效...
的 Perl6 运算符——whatever-star 可用于创建 lambda 表达式,序列运算符用于创建惰性列表——它也是调用运行时固有代码的命令式语句。
让我们考虑一些其他的编程范式,特别是函数式和面向对象的编程。
函数范式本质上是声明性的,因为它将计算建模为集合之间的关系。
面向对象范式本质上是命令式的,因为它将计算建模为有状态对象之间的通信,称为消息传递。
有些语言是纯粹的,这意味着所有计算都符合范式。例如,Haskell 是一种纯函数式语言,Smalltalk 是一种纯面向对象的语言。
但是,这并不意味着函数式语言相应。面向对象语言阻止命令式响应。声明式编程。在实践中,你经常使用命令式的函数——你输入一个输入值来得到一个输出值。面向对象的编程正好相反:对象接受的一组消息声明了它的接口。
有些人不同意 OO 是一个必要的概念,所以这是我的推理。
面向对象要点:
这意味着 oo 编程需要object(!) 持有的可变状态。如果您通过创建一系列对象来模拟状态变化,那么您就是在破坏这些不变量,就这么简单。
Flamebait:如果您不同意这种面向对象的定义,请与 Alan Kay 一起讨论。
许多不同的概念促成了面向对象编程的概念。维基百科列出了其中的大部分。
我将通过使用Objects with Behaviors来描述 OOP 的本质。
维基百科通过以下三个属性来描述对象:
很多面向对象的语言都有类的概念,但实际上也有像 JavaScript 这样的基于原型的语言。
函数式语言也可以使用类(例如 Haskell 中的类型类)。但是仅仅因为它们有类并不意味着它们是面向对象的或允许面向对象的编程。以 Haskell 为例:你甚至没有对象!没有“身份”这样的概念!您所能做的就是编写纯函数!
仅仅因为有人使用了一个名为“类”的术语,这并不意味着他们正在做面向对象的编程!
OOP 是关于具有行为的有状态对象。尽管对象的行为不必修改该对象,因为可以创建新对象,但您将完全放弃对对象的需求。您将不再需要身份,因为对一个对象的更改是否由对同一对象的其他引用反映并不重要,因为不再有任何更改。您所需要的只是用于数据隐藏和封装的值(没有身份)和模块和/或类。
所以是的,命令式编程是 OOP 所固有的。