面向对象需要哪些功能?


9

我只是想知道,语言或库必须提供什么功能才能将其定义为“面向对象”。是否可以在具有适当功能的任何通用编程语言中或多或少地实现对象定向?还是只能通过专门宣传它们支持面向对象编程的语言才能实现?

例如,看下面的C代码:

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE);
SDL_FreeSurface( screen );

此处讨论的代码。

现在,上面的代码不使用继承,运行时多态性(?),虚函数等。但是对我来说,它似乎是非常面向对象的。

面向对象是否只是在编写基于不需要对象或编程语言或提供的特殊模式或功能的可创建和可破坏的数据结构(例如对象,类,结构等)的代码?


2
OOP通常需要对象。但是,可以用大多数语言编写看起来像OOP的代码(我怀疑您可以说“该程序集看起来像是OOP”)
Raynos 2012年

上面的代码未使用if语句或循环。它不使用乘法或加法。您不能使用两行代码以及显示的内容列表来做出任何判断。从这两行代码中,我可以推断出它是一种严格的惰性函数式编程语言,而不是OO语言。使用两行代码作为概括的一部分并不是一个真正的问题。
S.Lott 2012年

链接也包含在我判断过的上述代码中。另请注意,这不是一种判断,我在您是否可以将其视为OOP。
ApprenticeHacker 2012年

简单的答案是肯定的。我的意思是这个。从代码示例中,您无法判断OOP。这是一个琐碎的定义问题。该语言被定义为OOP语言,或者不是。任何给定的代码样本都可能不需要所有OOP功能。确实,OOP代码可以使用很少的功能。例如,在Python中,1+2实际上是面向对象的。它是一个从两个现有对象构建新对象的构造函数。使用代码示例不会显示任何内容。
S.Lott,2012年

使用此定义并将其与语言(不是两个代码示例)进行比较有什么问题? en.wikipedia.org/wiki/...
美国洛特

Answers:


11

根据发明了“面向对象”一词的艾伦·凯,

对我而言,OOP意味着仅消息传递,本地保留和保护以及状态过程的隐藏以及所有事物的极端后期绑定。可以在Smalltalk和LISP中完成。可能还有其他系统可以做到这一点,但我不知道它们。

消息传递(在Smalltalk中实现)是一个与多态性可比的概念,但是功能更强大(至少比C ++或Java支持的多态性强)。可以用所有语言来完成,但是如果语言不直接支持它会很痛苦。基本上,这意味着对象可以互相发送包含任何内容的消息,并且amd可以做出反应,但是它们希望对收到的消息进行响应。为了完全支持消息传递,必须有一种方法使对象可以灵活地对消息做出反应,而无需在源代码中枚举它们(基本上是方法/函数定义所做的事情)。

本地保留和保护以及状态处理(即AKA封装)的隐藏可以通过所有语言的约定来完成,但这有点作弊。实际上,在语言级别上的本地保留似乎是所有声称是面向对象的语言(许多不共享)的一项功能-通常存在一种创建具有多个实例的复合数据类型的方法。另一方面,保护和隐藏通常仅是按惯例进行的。

所有事物的后期绑定 -C的缩放比例实际上与Kay的设想相去甚远(C ++也是如此,而Java更接近)。可以伪造(请参阅COM),但是使用起来很麻烦。

请注意,凯如何不提及继承。在同一封电子邮件中,他写道

我不喜欢Simula I或Simula 67做继承的方式(尽管我认为Nygaard和Dahl只是伟大的思想家和设计师)。所以我决定将继承作为内置功能保留下来,直到我更好地理解它为止


4
究竟Java和C#比C ++更接近于后期绑定?
fredoverflow

@FredOverflow:Java在首次使用类定义时会在运行时延迟加载它们,并通过一种极其灵活的机制隐式地进行加载,该机制可以轻松地添加新类甚至即时生成它们。C ++要求您重新链接可执行文件或显式加载库。C#的情况似乎不像我想的那么清楚,因此我删除了对ti的引用。
Michael Borgwardt

5

面向对象的编程与语法功能无关,它是一种编码和设计哲学。对象的概念的核心是对象,它是一种将状态与例程组合在一起以对其执行操作的构造(或根据您的观点,对消息的响应)。OOP的另一个重要方面是封装:将实现细节包装到不透明的结构中,并通过定义明确的接口将它们连接起来。OOP理论中的几乎所有其他内容都可以追溯到这两个基本原理。

因此,任何可以某种方式对对象(包含数据和代码的实体)进行建模的语言都可以用于封装。例如,在C语言中,您可以使用函数指针将函数存储在结构中,并且可以使用标头/源文件系统来实现封装。这不方便,但是足以做OOP。您甚至可以弯曲Haskell或ML之类的东西来进行OOP,如果有人能提出一种在装配中进行OOP的方法,我也不会感到惊讶。

但是,从实用的角度来说,如果一种语言为显式的面向对象编程提供了完整的语法功能,则可以将其称为“面向对象”。通常,这意味着这种语言应具有:*对象的概念*方法调用或消息传递的概念*控制对象成员访问的简便方法*定义接口的简便方法

因此,如果它遵循OOP原则并使用可用的OOP语法,则将其称为面向对象的代码。

顺便说一句,您的代码示例可能确实使用了多态性和虚函数,尽管C语法没有使它显而易见。我不是SDL方面的专家,但我希望SDL_surface能够代表各种不同类型的表面,每种表面都有其特定的实现集-将某些内容写入内存位图,并将其写入屏幕表面需要完全不同的方法代码,但接口(将an SDL_surface*作为参数的函数)保持不变。就像这样,它也实现封装:您不能直接访问曲面的基础表示,您必须通过知道如何处理的函数SDL_surface,因为这就是您所拥有的全部。这是如何在C中进行OOP的一个很好的例子。


但是,抽象数据类型,数据建模和封装并不是OO独有的(正如您简要提到的那样)。我更愿意基于OO的更多独特功能(方法调用的动态绑定,通过所述方法调用进行的多态性等)来描述OO
hugomg 2012年

4

我对OO的理解是OO是一种思维方式和一种实现,它基于这样的思想:可以由一个工作人员(对象)或单个工作人员(对象)的协作通过这些工作人员之间的消息传递来完成计算任务(对象)。这种运行时行为需要可靠的静态和动态结构来启用它。

实现OO的特定语法不是确定语言是否是OO的关键。例如,Smalltalk和C#具有不同的语法,但是两者都是OO语言(在不同程度上)。关键是给定的语言是否保留了上述哲学并提供了所需的植入方法。


2

当我还是一个学生时,我被教导面向对象的程序设计立足于三个支柱:

  • 封装
  • 多态性,并且
  • 继承

语言必须支持这些功能,才能被视为面向对象的语言。

请注意,这里描述的是一组功能,而不是语法。因此,您是否必须编写

type obj; // or type obj = new type;
obj.func(arg);

要么

type* ptr = create_type();
func(ptr, arg); 

没关系

因此,您确实可以按照C中的面向对象范例进行编程。但是该语言对此不提供任何支持,这使它成为一个相当痛苦的练习。这就是为什么C不被视为面向对象的语言的原因。


2
教导这些“支柱”对世界可能弊大于利。封装是好的,但是仅此而已。
tdammers

1
他们在这份名单中,所以他们似乎被广泛接受: en.wikipedia.org/wiki/...
美国洛特

您能解释为什么多态性和继承性不好吗?
MathAttack 2012年

@MathAttack:你在跟说话吗?因为我当然没有这么说。
2012年

1
@missingno:某些范式不一定必须具有某些独特性才能被认为对区分范式很重要。封装对于OOP不再是唯一的,而对于结构化编程而言,功能则是唯一的。
2012年

2

可以使用任何适当的通用语言进行OO。

这是比较容易做到这一点在“面向对象”的语言,因为你有惯用的结构可用,不必诉诸像用C OO -这是可能的,但可怕的。

OO构造是由语言本身,由其标准库还是由其他库提供的,都没关系,因为某些语言(例如Scala)允许库添加语言构造,因此从程序员的角度来看几乎是不可能的区分核心语言提供的内容和库提供的内容。


2

如果您查看被OO广泛接受和未被OO接受的语言范围,则该测试似乎是对包含多态性的支持(又称子类型多态性,但Cardelli多态性是Cardelli在这篇论文向我(以及我认为很多其他人)介绍了多态性的分类)。即,根据一个或多个值的类型,某些变量具有不同类型的值的可能性以及某些调用将其分派到不同例程的可能性。其他所有内容都以不被OO接受的语言呈现,或者被很好地被视为OO的语言缺失。

非OO语言提供了与OO语言相关的两个其他主要特征:

  • Ada83很好地提供了封装;
  • 继承是由Oberon提供的(Oberon很有趣,Wirth希望提供一种尽可能少的粗俗的OO语言,但是不得不重新审视他的概念以得到一种语言-Oberon-2是OO)。

1

面向对象的定义为

还可以查看维基百科条目。这些是语言必须提供的功能,以将其定义为面向对象。

如果您的代码是面向对象的编程语言,请考虑它是面向对象的。即使您编写的东西看起来像是过程性的,它也将通过封装[也许]使用多态性作用于类中对象中的方法:)

关于您的最后一个问题,答案可能是。是。面向对象基本上只是作用于对象上的方法,并将这些对象作为参数传递。


3
由谁定义?
Michael Borgwardt
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.