在The Well Grounded Rubyist(excerpt)一书中,David Black谈到了“阶级/对象鸡与蛋悖论”。我很难理解整个概念。
有人可以用更好/更容易/类比/其他术语解释它吗?
引用(强调我的):
班级
Class
是其自身的一个实例;也就是说,它是Class
宾语。而且还有更多。还记得课程Object
吗?好吧,Object
是一个类...但类是对象。所以,Object
是一个对象。和Class
是一个班级。Object
是一个类,Class
是一个对象。哪个先来?如何创建类
Class
除非 班级Object
已经存在?但怎么会有一个班级Object
(或任何其他类),直到有Class
类可以 实例?至少就目前而言,解决这一悖论的最佳方法是忽略 它。为了获得,Ruby必须做一些鸡肉或鸡蛋的东西 类和对象系统启动和运行 - 然后,循环 和悖论无关紧要。在编程过程中,你就是这样 需要知道类是对象,被调用的类的实例
Class
。(如果你想简要地知道它是如何工作的,就像这样:每一个 object有一个内部记录,它是一个实例的类,和 对象
Class
内的内部记录指向Class
。)
答案 0 :(得分:13)
您可以在此图表中看到问题:
Ruby Method Lookup Flow http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png
所有对象实例都继承自Object
。所有类都是对象,Class
是一个类,因此Class
是一个对象。但是,对象实例继承自其类,Object
是Class
类的实例,因此Object
本身从Class
获取方法。
然而,正如您在图中所看到的,没有循环查找循环,因为每个类有两个不同的继承“部分”:实例方法和“类”方法。最后,查找路径是理智的。
N.B。:此图反映了Ruby 1.8,因此不包含Ruby 1.9中引入的核心BasicObject
类。
答案 1 :(得分:1)
实际上,您需要了解的是 Object 是所有类的母亲。所有类都扩展 Object 。您将在编程,理解继承等方面使用这种关系。
EG;您可以随时在任何对象的任何实例上调用 hash()吗?为什么?因为该函数出现在 Object 类中,并且所有类都继承该函数,因为所有类都扩展了 Object 。
就 Class 的想法而言,这种情况的发生频率要低得多。类 Class 的对象就像一个蓝图,就像在你手中拥有类,而不是创建它的实例。还有一点,但没有冗长的例子,这是一个很难描述。请放心,当(如果有的话)使用它的时候,你会看到它的目的。
所有这些摘录都说 Object 有一个类 Class 而 Class 是一个对象,所以必须扩展对象。它是循环的,但却无关紧要。答案隐藏在编译器的某个地方。
答案 2 :(得分:1)
关于哪个是第一个标准,有两种Ruby对象:
有关Ruby对象模型的详细说明,请访问www.atalon.cz。
答案 3 :(得分:1)
我知道我的答案迟了至少3年,但我最近才了解Ruby,我必须承认文献有时会出现(在我看来)误导性的解释,即使有人处理一个非常简单的问题。而且,我(并且)对这样令人震惊的短语感到惊讶:
"The best way to deal with this paradox, at least for now, is to ignore it."
作者D. Black在问题中引述了这一态度,但这种态度似乎无处不在。我在物理学界经历过这种趋势,但我并不怀疑它也通过编程传播。我并没有说明没有人理解潜藏的是什么,但似乎至少有趣的是为什么不提供(确实)非常简单和精确的答案,因为在这种情况下有一个,而不是在内部调用任何模糊的词,如“悖论”说明。
这种所谓的“悖论”(即使它绝对不是这样的东西)来自(至少是误导性的)信念“作为(子类)的实例”应该是“作为一个元素” “(比方说,天真集理论),或者换句话说,一个类(在Ruby中)是包含共享一些公共属性的所有对象的集合(例如,在这种天真的解释下,类String包括所有的字符串对象) 。即使这种天真的观点(我可以称之为“成员解释”)可能有助于理解孤立的(而且相当容易的)类,如字符串或符号,但它确实产生了一种清晰的矛盾与我们天真的理解(以及公理化的一种)因为它与冯诺依曼的集合论的规律性公理相矛盾,如果有人知道我所说的是成员关系,那么对象就不能成为自身的一个元素,正如前面的解释所暗示的那样,关于对象类。
如果用如下非常简单的模型摆脱这种误导性的成员资格解释,就可以很容易地避免前面提到的问题。 我猜我的下面的解释是专家所熟知的,所以我声称没有任何原创性,但也许它没有在我将要提出的(简单)术语中改写:在某种意义上我完全惊讶(显然)从一开始就没有人用这些术语说明,我的目的只是强调我认为的基本结构。
让我们考虑一组(基本)对象,它由Ruby拥有的所有(基本)对象组成,提供从O到O的映射f(或多或少是.class方法),满足f的组成图像本身只有一个元素。 后一个元素(或对象)表示为Class(实际上,您知道的是类Class)。 我很想用LaTeX代码写这篇文章,但我不太确定它是否会被解析并转换成典型的数学表达式。 映射f的图像(根据定义)是Ruby类的集合(例如,String,Object,Symbol,Class等)。 Ruby程序员(即使他们不知道它)解释前面的结构如下:当且仅当y = f(x)时,我们说对象“x是y的实例”。顺便说一下,这告诉我们你究竟是Class的一个实例(即它本身)。
现在,我们需要更多装饰这个简单的模型,以获得类和功能的完整Ruby层次结构(在地图f的图像上强加一些固定成员的存在,图像上的部分顺序地图f,以便定义子类以获得后续继承等),特别是为了获得有趣的upvoted的漂亮图片,但我想每个人都可以从我给出的原始模型中弄清楚这一点(我已经写了一些页面在阅读了几本Ruby手册后,我自己解释了这一点。如果有人认为有用,我可以提供一份副本。
答案 4 :(得分:1)
首先出现:类Class 或类Object ?
每个类都是类Class的一个实例。因此,类Object 是类Class 的一个实例。因此,您需要类Class 来创建类Object 。因此:
- 类 存在于类对象之前。
醇>
类Class 是类Object 的子类。因此,您需要类Object ,可以从中创建类Class 。因此:
- 类对象 存在于 类Class 之前。
醇>
所以声明-2与声明-1冲突,所以我们有我们的鸡和&鸡蛋困境。或者你可以接受它作为循环定义!