术语“纯OO语言”的正式定义?


13

我想不出SO兄弟姐妹之间有更好的位置提出这样的问题。最初,我想问“ python是纯OO语言吗?” 但是在尝试定义术语时,考虑到麻烦和人们的不适感,我决定从为术语本身获得明确的定义开始。

从创造该术语的Alan Kay博士的来信开始,这是相当公平的(请注意在生物学上类似于细胞或其他生物的灵感)。

有以下几种方法可以完成任务:

  1. 通过列出可以表现出(或不能表现出)某些独特且足以定义该术语的属性的编程语言来进行比较分析(尽管Smalltalk,Scala,Java等)是可能的示例,但IMO这种方式似乎并没有真正完成也不富有成果
  2. 给出一个正式的定义(或接近它,例如以学术或数学的风格)。
  3. 给出一个完全依赖于具体语言的语义上下文或先验编程经验的哲学定义(社区一定有一定的成功解释的机会)。

我当前的版本:“如果某种编程(形式化)语言可以(在语法上)区分操作数和操作数,并推断每个操作数的类型是否是对象(就OOP而言),那么我们称之为只要该语言中至少有一种类型是对象,那么这种语言就是一种面向对象的语言。最后,如果所有类型的语言都是对象,我们将这种语言定义为纯(强)面向对象的语言。”

将不胜感激。如您所见,我只是根据术语“对象”(通常完全称为对象类)来进行定义。

[编辑]

另外,我使用(很容易理解的)类型概念,就像在类型化语言中一样。数据类型编程或面向类型的编程不仅是对程序文本的语法解释(即,如何处理文字和数据变量的某些值-演变为类型安全性的某种东西),而且可以归因于语言语法并以正式方式进行研究(使用数学逻辑)称为类型系统。注意,要求特定类型系统具有所谓的通用类型是定义OO语言纯净性的方法之一(有一些方法可以在语义上进行扩展)。

NB

如何回答

  • 如果您指定支持或解释您对术语和概念的理解的书或参考文献(通常是一个好的定义涵盖或参考了除基础知识以外的所有相关概念),它会有所帮助。
  • 如果不清楚,请在可能的情况下注明答案/定义的缩进类别(请参见上文:1-以语言为例,2-数学逻辑,3-技术描述和编程原理)
  • 分类很重要(也是因为术语OO包含在术语OO中),同时回答尝试将OO范式的元素与其他众所周知的方法进行混合(并且绝不会造成混淆/重叠),例如,通常可以覆盖模块化编程的元素/包含OO编程):尝试将OOP与功能编程,逻辑编程(尤其是高度专业化的),Abstarct数据类型(ADT),模块化,元编程(泛型和LISP的宏扩展时间)(包括或作为其一部分)进行区分,合同(例如Eiffel),面向方面(AO)(声明性和功能性分类之间的差异以及Dijkstra结构化的历史定义很明显)

关于难以给出正式定义的困难:令人惊讶的是,以某种逻辑(正式)系统(最有可能基于类型)的形式给出OOP的数学描述,并一个接一个地定义一个概念非常容易。甚至可以尝试通过将形式主义应用于类型安全检查新的语言设计方面来做一些更实际的事情,而不仅仅是抽象的娱乐或练习(还包括在直觉类型理论中对OOP的查找公式,从属类型,在FOL形式主义中独立地作为lambda计算)并仅使用类别理论)。这里的重点是毫不奇怪IMO最初对OOP的最不完全了解(在计算机工程中),使IMO的这种表达有很大的偏颇(有缺陷),并最终在之后几乎无法访问(因此几乎不对编程世界有所贡献-也许除了某些百分比会通过从应用程序世界中找回应用程序)集成到流行语言中)。

因此,是的,很难给出一个准确的“好”定义,而不仅仅是给出定义。但是我很高兴在这里提出这个问题,因为你们的经验和直接参与,伙计们。


2
好吧,您已经为Python回答了自己。“没有”。
psr 2012年

2
+1是一个很好的问题,但是您的版本由于类型对象是不同的东西而有些瑕疵。
弗兰克(Frank)

5
@JoachimSauer:他在Squeak邮件列表上的另一封邮件中说,“最大的想法是消息传递”,他后悔曾经将其称为“面向对象”,而应该将其称为“面向消息”。例如,Erlang是一种完全面向对象的语言,可以满足Kay博士的所有标准,而对“对象”,“方法”,“继承”,“类”,“原型”或类似的东西都没有任何概念。
约尔格W¯¯米塔格

1
这可能是一个很好的例证,说明语法不足以定义OO语言。如果可以证明OOP(例如,作为一种工具)仅是语义上的(与语法无关),那将完全改变(反转)我的问题!
Yauhen Yakimovich 2012年

2
@YauhenYakimovich这是讨论OOP的根本问题之一,每个人和他的狗都有自己的想法。相反,结构化编程和功能性编程可以非常简单地定义。这使我提出质疑:OO是否具有与宗教而非科学类似的特性。
里奇·克拉克森

Answers:


19

OO,根据艾伦·凯(Alan Kay)的观点,就是消息传递,仅此而已。您将看到,诸如多态性和封装之类的质量实际上是从消息传递中得出的。

现在的立场实际上非常极端,因为这基本上意味着只有Smalltalk和其他语言才有资格。

我认为您可以将OO定义为在实体上构建系统,该实体完全封装其状态,并且由于其固有的多态性而可以互换。因此,可以争论一种纯粹的面向对象的语言,以确保始终满足这两个核心素质。使OO语言“不纯”的原因是允许创建不满足这些条件的构造的机制,例如:

  • 声明公共领域
  • 声明只能容纳特定类及其子类实例的变量(即,应根据接口键入变量,这是生物学对象在凯的解剖学中交流的意思),如果所涉及的类是最终类,则该变量将变得更狭窄留下了更少的多态性空间
  • 声明原语

再说一遍,恕我直言,语言纯净不是弱项,而是强项。OO不是灵丹妙药。没有单一的范例。


2
为“ OO不是灵丹妙药” +1。
Andres F.

1
@AndresF。请注意,OOP的实用价值以及与编程相关的其他理论知识实际上并不是问题的一部分。很明显,一个人可以以一种非常成功的方式编写代码,而无需对编程技术或理论有任何深入的了解(反之亦然)。既不OO语言的应用性能进行了讨论,等
Yauhen Yakimovich

@YauhenYakimovich哦,我知道。如果答案是题外话,我不会投票赞成。尽管如此,我还是喜欢一个我同意的主张。
Andres F.

@AndresF。当然:-)“ OO不是灵丹妙药”很可能是对的,以及我们缺乏完善的编程语言。但是究竟是什么使OOP不再是银弹呢?正如良好的错误报告一样,我认为详细而精确的术语是解决此问题的方法。我花了很多时间来处理它,我真是好奇地将其提升到一个新的水平。OOP只是从一本编程书粘贴到另一本编程书的一堆创意吗?
Yauhen Yakimovich 2012年

@ back2dos +1用于根据Kay(Smalltalk,Objective-C)明确指出“消息传递”的作用。显然,他从未打算看到OOP向着今天的方向发展。但是我真的很喜欢Kay的想法,使对象不是数据(类型)。他确实推动将它们的生物学特性归功于他们,但最终以“消息传递”告终。
Yauhen Yakimovich 2012年

6

我将通过将其定义为使用OOP构造而不使用其他任何语言的语言来实现这一目标(就像纯FP语言使用具有不变数据的纯函数一样,仅此而已)。

尤其是:

  • 您的程序所操作的每个实体都是一流的Object-即没有基元,没有指针,没有数组等。
  • 您可以对对象执行的唯一操作是在对象上调用(可能是多态的)方法(==发送消息)。没有其他操作。
  • 所有数据都被封装 -即没有公共字段访问,您必须通过对象上的方法
  • 如果您具有一流的功能,那么它们也必须是对象 -因此,您需要执行类似的操作functionObject.call(param1,param2)
  • 没有全局变量 -如果您想要这样的话,则需要使用一个对象来表示当前的全局环境,例如,environment.getValue("myThing")或将变量放在类对象中

请注意,这仍然留下了很多选项:

  • 基于类与基于原型的对象模型
  • 如何实现继承(如果有的话)
  • 您是否对方法进行单次调度或多次调度
  • 您的对象是静态类型还是动态类型
  • 用于方法调用的确切语法(例如,您可以为getter / setter等使用一些语法糖)

1
这些是很好的定义,但不要将对象的实际情况与单纯的语法混淆。仅仅因为函数和全局变量具有友好的语法,它们实际上实际上就是对象。
ddyer 2012年

@ddyer-如果它确实只是语法,那是正确的,但是我认为,如果语法还引入了不同的语义,那么它可能会破坏“纯净性”。例如,使用全局变量globalVariableName来访问全局变量与在对象上进行方法调用的语义不同,后者是访问纯OOP中非局部值的唯一方法。
mikera 2012年

我认为“一切”都必须是合格的。如果一种语言根本没有反射能力(例如,它不能通过抽象名称引用对象的方法或将其存储在变量中),那么方法是否也必须是对象?是引用对象吗?引用和对象甚至是不同的东西吗?
Joachim Sauer 2012年

@Joachim-好点。我将其限定为“您的程序在其上运行的每个实体”,以区分变量名和语法构造等语言中的对象与元对象。显然,如果您的程序实际上是通过反射对此类事物进行操作,则需要将它们作为真实对象进行修饰,但这并不总是必需的。无论如何,如果您能想到更好的资格条件,请随时对其进行编辑!
mikera 2012年

“基于类的对象模型与基于原型的对象模型”:但是我要说的是,在两种情况下,您都有某种分类,即,将具有共同结构和行为的对象组合在一起。
Giorgio 2012年

4

关于所谓的“ OO语言”的讨论总是有点令人洗脑。即:

“有人告诉我,语言X是OO,因此语言X等于OO,那么每种缺少语言X特性的语言都不可能是OO。而且因为我用语言X编写代码,所以我所做的一切都是OO。 ”

术语面向对象设计可归结为三点:

  1. 带有自治对象的模块化设计,这些对象不了解有关程序其余部分的不必要信息,也称为尽可能松散的耦合
  2. 将数据封装在对象内部以防止外部访问(有意和无意)。
  3. 明确指定对象之间的依赖关系。在实现松耦合的同时,也使程序更易于维护和扩展。

1)是纯程序设计,可以用任何编程语言来实现。但是,某些语言具有有用的功能,例如类/结构和专用关键字。

2)主要是程序设计,但是如果没有语言支持就无法完全实现,因为您需要使用诸如private / static之类的语言机制来防止意外使用。

3)主要是程序设计。通常存在三种不同的依存关系:“对象X包含对象Y”,“对象X是一种Y”和“对象X与对象Y交互”。有许多语言功能可帮助解决这些依赖性:继承/多态性,抽象基类等。

现在,如果我们看上面的内容,我们可以看到您几乎不需要任何语言功能来编写OO程序。这些功能使它变得更加容易。

通过使用一些模糊的向后逻辑无法实现上述目标:仅仅因为您使用class关键字,您的程序就不会自动获得模块化设计。仅仅因为您使用继承,它并不自动意味着您的对象依赖关系才有意义。具有OO功能的语言仍将允许class TheWholeBloodyProgram“动物继承猫”之类的东西。

可悲的是,在这类讨论中很少提及良好的面向对象程序设计的主题。洗脑的程序员只看语法,然后大惊小怪,例如“ C ++具有原始数据类型,因此您的C ++程序不是OO”,然后他们便以自己喜欢的语言编写了一个彻头彻尾的可怕程序,而没有使用任何提示。程序设计。

要回答这个问题:很少(如果有的话)支持适当的OO程序设计。只要程序员不知道面向对象设计的含义,找出具有某些与OO相关的功能的语言就无关紧要。声称某些语言是面向对象的程序员最有可能没有完全理解OO的概念。询问可能的OO程序员如何设计OO程序。如果他们要做的第一件事就是开始大喊语言关键字,那么您可以放心地假设他们不了解OO设计。

也许在原始源代码之上还有一些花哨的高级UML风格的工具,它迫使程序员只能编写具有良好的面向对象设计的程序,但我对此表示怀疑。面向对象编程的最佳设计工具很可能仍然是人脑和常识。


您能否阐明您的定义与例如带有抽象数据类型的模块化编程的区别?我认为您的路线正确,但是我还看不到火车!
约尔格W¯¯米塔格

@JörgWMittag不一定有什么不同,传统的ADT:s可以使用面向对象的设计编写,并带有适当的封装,setters / getters,继承它的方式等。但是也可以不考虑OO设计而编写它们。->

2
@JörgWMittag例如,如果您有诸如C之类的语言,并且对OO的语言支持有限,那么以面向对象的方式编写ADT:s将非常棘手。最常见的错误是将ADT的分配留给了调用者,即给他们一个公开的结构,其中暴露了所有内部结构,从而破坏了封装。在C中执行此操作的正确方法是通过所谓的“不透明类型”(不完整类型),尽管没有多少C程序员知道使用它们。

@Lundin:在JörgWMittag发表的文章中,作为对另一个答案的评论,在ADT和OO之间有一个(IMO)有趣的比较。
乔治

我从一些UML书中记得(可能)还有一个要点0。抽象性(强调抽象表示对于对象间关系如多态性,继承,聚合等至关重要的重要性)。
Yauhen Yakimovich 2012年

2

不,没有正式甚至有用的定义,也永远不会有。对于某些人来说,OOP的意思是“通用基类”和“必须使用引用语义,最好与垃圾收集器一起使用”,您甚至可以对语法提出质疑,这是有史以来最不相关的事物之一。

最终,首先,您必须回答问题“什么是对象?”。心胸狭窄的人将坚持从毫无意义的通用基类继承,并不必要地分配给垃圾收集器以限定资格。但是我更喜欢一个有用的定义。OOP的目的是拥有一些数据,以及可以对这些数据调用的某些功能。所以

  • 一个对象拥有一些状态,并在该状态上提供一些功能。

在这种情况下,甚至int合格。毕竟,当您用C ++编写可以接受基元或对象的模板代码时,很难说出基元在任何实质性方面都是不同的。没有什么有意义的不同有关Vector v1, v2; v1 + v2;,而不是int v1, v2; v1 + v2;(除了蹩脚的初始化语义,一个必须承认)。同样,这允许lambda和此类事物成为对象,因为它们持有状态(即捕获状态)并在该状态下提供函数来调用lambda。

幸运的是,我们还可以将指向自由函数的指针归类为对象,因为它们既保存状态(一个地址),又保存该状态上的一个函数(以调用它)。因此,即使您说所有的自由功能实际上都是全局函数指针,也应允许使用自由功能。


2
我认为不需要这种区别。但是其次,它们具有与任何其他对象相同的身份-地址/引用比较。除了比较地址之外,您不能区分两个状态相同的对象这一事实与以往并不遥远,它适用于所有对象。
DeadMG 2012年

5
-1。从无用和不必要的unnecessary斥开始,不久便转向了人为攻击,并且即使是事实事实(OOP的定义)也唯一是错误的。请阅读的了解数据抽象,再访威廉·R·库克为一个抽象数据类型和对象之间的区别。
约尔格W¯¯米塔格

1
“我认为不需要这种区分。”:但是这种区分是对象普遍接受的特征之一。当然,您可以开发自己的对象概念,该概念与通常接受的对象不同。您完全可以这样做。
乔治(Giorgio)2012年

2
@Jörg,我希望与众不同。我并不完全同意这篇文章,但是在第一段中将警告称为“无用”或“大声”是不合理的。关于OOP的定义尚未达成共识。这是一个简单且广为接受的事实。该帖子的其余部分是OOP 定义。当然不是最广泛使用的,也不是我要提供的,但是,正如DeadMG所说,实际上是一个非常有用的工具。
Konrad Rudolph 2012年

2
@KonradRudolph:当我写我的评论时,该段的内容非常不同,包括将关心语法的程序员与种族主义者进行比较,甚至用名字提及该站点的特定用户。
约尔格W¯¯米塔格

0

您可以通过负面示例来思考。Java不是纯面向对象的语言,因为还有一些不是对象的原始类型。这些是整数,双精度数,数组等。在纯对象语言中,对象的语义适用于所有事物。

还有一个问题是,即使在对象框架内,有多少种语言不适合修改。在Java中,您无法为某些类(例如String或Class)定义新的子类。

哪种语言是纯净的?我想到的唯一的候选人是闲话。


Ruby也不是纯OO语言吗?
zxcdw 2012年

2
@zxcdw(和ddyer):确实是问题所在:没有人对“纯OO”有正式的定义,因此没有人可以对这个问题给出明确的答案。
Joachim Sauer 2012年
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.