【问题标题】:Does C's FILE have an object-oriented interface?C 的 FILE 有面向对象的接口吗?
【发布时间】:2009-06-24 23:43:47
【问题描述】:

通过标准C函数fopen等使用的FILE类型是否具有面向对象的接口?

我正在寻找有道理的意见,而不是一个绝对的答案,因为 OO 的定义因您问的人而异。它满足或不满足哪些重要的 OO 概念?

针对 JustJeff 在下面的评论,我不是在问 C 是否是一种 OO 语言,也不是在问 C(容易与否)是否允许 OO 编程。 (这不是一个单独的问题吗?)

【问题讨论】:

  • 您是在问 FILE 是不是类对象的,还是 C 是?因为人们似乎在回答不同的问题。
  • 如果面向对象不是一种技术而是一种语言特性(我相信),并且如果根据该定义,C 不是面向对象的,那么 FILE 不是面向对象的。但是,如果面向对象仅仅是一种技术,那么 FILE 可能是面向对象的。 (在那种情况下,我对此没有意见。)
  • 这不是一个单独的问题;鉴于 C 不(直接)支持对象,它不能为任何东西提供面向对象的接口。

标签: c oop


【解决方案1】:

C 是面向对象的语言吗?

在创建 C 和 FILE 时,OOP(面向对象编程)仅仅是一个实验室概念吗?

回答这些问题将回答您的问题。

编辑:

进一步的想法: 面向对象具体意味着几种行为,包括:

继承:你能从 FILE 派生新的类吗?

多态性:你能把派生类当作文件吗?

封装:你能把一个文件放在另一个对象里面吗?

方法和属性: FILE 是否具有特定于它的方法和属性? (例如。 myFile.Name, myFile.Size, myFile.Delete())

虽然有众所周知的 C“技巧”来完成与这些行为中的每一个类似的事情,但这并不是 FILE 内置的,也不是最初的意图。

我的结论是 FILE 不是面向对象的。

【讨论】:

  • 尽管该语言并非专门针对面向对象的开发,但这并不意味着您不能手动实现面向对象的接口(使用结构和函数指针)。以 GLib/GObject 为例。
  • fopen、fclose、freopen等函数不是FILE对象的方法吗?方法的显着特征仅仅是你通过 a.b 语法调用它们的语言语法吗?
  • 我认为 OO 的内容比这个问题的答案要多。
  • 就像 R.Pate 所说,您似乎将 OO-ness 定义为语法的属性。如果方法调用包含一个点,它就是面向对象的,基本上就是它听起来的样子。 fopen 对我来说似乎是“特定于文件的方法”。你不同意吗?至于封装,文件不是封装了所有的内部细节吗?您是否能够在 FILE 中浏览您不应该关心的实现细节?对我来说,它似乎封装得很好。多态性?我可以将套接字或标准输入/标准输出视为文件。这不是多态行为吗?
  • @jalf:仍然不能继承它。子类化通常被视为 OO 的重要组成部分,因此如果没有子类化 FILE 的能力,它不符合完全功能术语的定义,不考虑语法。
【解决方案2】:

如果 FILE 类型是“面向对象的”,我们大概可以以某种有意义的方式从它派生。我从未见过这种推导的令人信服的例子。

假设我有新的硬件抽象,有点像套接字,称为虫洞。我可以从 FILE(或套接字)派生来实现它。不是真的 - 我可能必须对操作系统内核中的表进行一些更改。这不是我所说的面向对象

但这整个问题最终归结为语义。有些人坚持认为任何使用跳转表的东西都是面向对象的,而 IBM 一直声称他们的 AS/400 盒子是面向对象的,直通式和直通式。

对于那些想陷入疯狂和愚蠢的深坑的人,即 USENET comp.object 新闻组,这个话题几年前就在那里进行了相当详尽的讨论,尽管是疯狂和愚蠢的人。如果您想深入了解这些深度,Google Groups 界面是一个不错的起点。

【讨论】:

  • 取决于您如何定义派生。套接字和许多其他东西也很适合 FILE 抽象。在posix中,几乎所有东西都是一个文件。它们都是同一个接口的派生吗? (顺便说一句,我没有对你投反对票,只是为了记录。)
  • 哇! Neil 的代表从 21.9K 增加到 21.9K,您的支持!再来一个,让我们看看时钟超过 22K。
  • 一定是发生了一次代表重新计算。不幸的是,我已经超过上限,所以更多无偿的赞成票不会产生任何影响。不过不要让这阻止你!
  • @Neil:这是否意味着所有那些不允许派生('final class','sealed'等)的类(在其他通常被认为是OO语言的语言中)不是OO 给你?
  • @R.Pate 这些语言确实允许派生——它们也允许派生。你似乎在建立一个错误的二分法。坦率地说,我对一种语言是否是 OO 并不是很感兴趣——我更感兴趣的是它是否有用。
【解决方案3】:

从学术上讲,实际文件当然是对象。它们具有属性,您可以对它们执行操作。并不意味着 FILE 是一个 class,只是说,需要考虑的 OO 度数。

然而,试图说 stdio FILE 接口符合 OO 的问题是,stdio FILE 接口不能很好地代表文件的“对象性”。您可以在普通的旧 C 语言中以 OO 方式使用 FILE,但当然会失去 Java 或 C++ 提供的语法清晰度。

可能应该进一步补充一点,虽然您不能从 FILE 生成“继承”,但这进一步取消了它作为 OO 的资格,但您可能会争辩说,这更多是其环境(纯 C)的错误,而不是文件即对象本身。

事实上 .. 您可以可能为 FILE 提供一个类似于 java 接口的案例。在 linux 世界中,您可以通过 open/close/read/write/ioctl 调用来操作几乎任何类型的 I/O 设备; FILE 功能只是这些功能的覆盖;因此,在 FILE 中,您有一个类似于抽象类的东西,它定义了“抽象 i/o 设备”上的基本操作(打开/读取/等),将其留给各种 派生类型用特定类型的行为充实那些。

当然,在一堆 C 代码中很难看到 OO,而且很容易破坏抽象,这就是为什么现在实际的 OO 语言如此受欢迎的原因。

【讨论】:

  • 是不是因为语法不清晰就不是 OOP?您认为语法清晰是 OOP 的一项要求吗?
  • 个人?不。我认为OO-ness最终存在于设计中。某些语言的语法允许仅通过实现来表达设计的这些方面,这一事实仅仅是一种精巧。相比之下,有很多经典的过程/结构化编程是用 Java 完成的,并且被吹捧为“OO”只是 b/c“语言是 OO”,好像该语言的 OO 特性以某种方式灌输了其中呈现的任何内容本质上是 OO。
  • “好像语言的 OO 特性以某种方式将它所呈现的任何东西都灌输为天生的 OO”——对我来说似乎很真实。反过来呢:如果一种语言的 OO 支持很少或根本不存在,这是否会使其中呈现的任何内容本质上非 OO?
  • 什么样的事物可以称为 OO?设计可以是OO吗?当然!语言可以是面向对象的吗?确实!系统的实现可以是OO吗?是的,在某种程度上独立于底层语言是否是。语言的一部分可以是面向对象的吗?你也可能会问,一片草可以是草坪吗?
  • 哈哈。真是一团糟。删除。删除。删除。
【解决方案4】:

这取决于。您如何定义“面向对象的接口”?正如 abelenky 帖子的 cmets 所示,很容易构造一个论点,即 FILE 是面向对象的。这取决于您所说的“面向对象”是什么意思。它没有任何成员方法。但它确实具有特定的功能。

它不能从“常规”意义上派生出来,但它似乎是多态的。在 FILE 指针后面,实现可以有很大的不同。它可能是一个文件,它可能是内存中的一个缓冲区,它可能是一个套接字或标准输出。

它是封装的吗?好吧,它本质上是作为指针实现的。除非您在其上调用适当的 API 函数,否则无法访问文件所在位置的实现细节,甚至文件名。这对我来说听起来很笼统。

答案基本上是你想要的。如果你不希望 FILE 是面向对象的,那么以 FILE 无法实现的方式定义“面向对象”。

【讨论】:

  • 我不认为 FILE 可以从任何合理意义上的派生词派生而来。 FILE 不是套接字,文件不是缓冲区,文件不是流。它可能包含任何这些元素,但这似乎是组合而不是多态性的一个例子。不过,您的总体观点已被采纳。 “面向对象”没有 ANSI/ECMA 标准。我们能做的最好的就是常见用法,我们可以整天为此争论不休。
  • 我喜欢你的回答 jalf。这正是我会说的。我一直认为 FILE 是面向对象的。
  • @Charles:我同意很难将其称为继承或派生,但它肯定是多态性,而不是组合。 FILE 对象的行为会根据您使用的众多实现中的哪一个而改变。
【解决方案5】:

C 具有面向对象的前半部分。 封装,即你可以拥有像 FILE* 或结构这样的复合类型,但你不能从它们继承,这是第二(虽然不太重要)一半

【讨论】:

【解决方案6】:

没有。 C 不是面向对象的语言。

我知道这是你不想要的“绝对答案”,但恐怕这是唯一的答案。理由是 C 不是面向对象的,所以它的任何部分都不能有“面向对象的接口”。

澄清:

在我看来,真正的面向对象涉及通过子类型多态的方法分派。如果一种语言缺少这一点,那么它就不是面向对象的。

面向对象不是像 GTK 那样的“技术”。这是一种语言特性。如果语言缺少这个特性,那么它就不是面向对象的。

如果面向对象仅仅是一种技术,那么几乎所有语言都可以称为面向对象,而这个术语将不再具有任何实际意义。

【讨论】:

  • 这真是奇怪的逻辑——“房子不是白色的,所以它的任何部分都不能是白色的。”。
  • 如果C缺乏面向对象的机制,它的任何部分怎么可能是面向对象的?
  • 通过自己用 C 编写机器。通过玩游戏与强制转换为 void 并构建自己的 vtables,您可以支持 C 中的继承、多态性和封装,这样做只是一件麻烦事.最初的 C++ 实现生成 C 源代码,然后编译。
  • 我不是要探究 C 的根源,而是要探究多态性的根源。为了避免纯理论,我专门询问了一个具体的例子,即(恕我直言)边界。多态性似乎是您的关键要求,也许是最重要的?还有其他要求吗?
  • 在一个单独但相关的说明中,如果 FILE 没有多态接口,文件描述符是否满足该要求?如果是,它们是面向对象的还是它们仍然缺乏哪些方面?
【解决方案7】:

oo 周围有不同的定义。我觉得最有用的是以下内容(受 Alan Kay 启发):

  1. 对象保持状态(即对其他对象的引用)
  2. 对象接收(和处理)消息
  3. 处理消息可能会导致
    • 向对象本身或其他对象发送消息
    • 对象状态的变化

这意味着您可以使用任何命令式编程语言(甚至是汇编程序)以面向对象的方式进行编程。纯函数式语言没有状态变量,这使得 oo 无法实现或至少难以实现(请记住:LISP 不是纯的!);纯声明性语言也应如此。

在 C 语言中,消息传递最常实现为函数调用,其中带有指向将对象状态作为第一个参数的结构的指针,文件处理 api 就是这种情况。尽管如此,C 作为一种语言不能归类为 oo,因为它不支持这种编程风格的语法。

另外,oo 的一些其他定义包括基于类的继承(那么原型语言呢?)和封装——在我看来这并不是真正必要的——但其中一些可以用 C 中的一些指针来实现- 和施法。

【讨论】:

  • 能否将您的分析应用到 FILE 接口?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
相关资源
最近更新 更多