【问题标题】:How do we talk about classes that do not inherit from the `Class` class in Ruby?我们如何谈论不从 Ruby 中的 `Class` 类继承的类?
【发布时间】:2019-11-08 15:32:24
【问题描述】:

BasicObject,据我所知,是 Ruby 中所有其他类的父类。然而,直到在层次结构的更底层,Class 类才被实际定义。因此,我很难理解BasicObject 是如何成为一个类的。

这里的区别仅仅是抽象的、面向对象意义上的 ruby​​ Class 与实际上是 Class 实例的类之间的区别吗?或者层次结构实际上是以BasicObject实际上是Class的一个实例的方式设置的?我很确定不是这样的。

如果 Ruby 中的“类”一词有两种含义,我觉得我缺乏讨论这两种类型的语言。如果确实是这样,我还能称一个不是Class 实例的类吗?

【问题讨论】:

  • 想要更困惑? Class 的超类是 ModuleModule 的类是 Class 所以 ModuleModuleClass 就像 Class 是 @9876543345@ 和 @9876 @。但是虽然ModuleClass 类的一个实例,但你不能拥有Module 类的实例。 Docs showing class Diagram 这都是通过匿名元类(singletoneigen)处理的,所以 BasicObject 是所有类的父类 BasicObject 的特征类是 Class 例如BasicObject.singleton_class #> <Class:BasicObject>
  • 您的问题令人困惑。 1) 在标题中您询问不从Class 继承的类,在正文中,您询问不是Class 实例的类。这是两个完全不同的东西。你问的是哪一个? 2) 有 no 类继承自 Class 并且有 no 类不是 Class 的实例,所以不管这两个问题中的哪一个你实际上意思是,这很难回答,因为你没有给出任何具体的例子。

标签: ruby class oop


【解决方案1】:

您可以将所有类视为 Ruby 世界中Class 的实例。值得记住的是,ruby 中的一切都是对象,包括类。是的 BasicObject 是 Ruby 中所有类的顶级父类。 BasicObject的类为Class,与BasicObject的父类为Class不同。

为了演示,假设我们定义了一个类Person

  • Person.new.classPerson
  • Person.classClass
  • Person.superclassObject
  • Object.classClass
  • Object.superclassBasicObject
  • BasicObject.classClass
  • BasicObject.superclassnil

证明Ruby中所有的类其实都是对象,你可以得到一个类的对象id。 BasicObject.object_id。在一般的面向对象的上下文中,一个类的一个类应该没有意义,除非类也是对象。

【讨论】:

  • 对,我必须牢记作为类的实例与子类之间的区别。我想我很惊讶A类可以是B类的父类同时也是B类的一个实例。这意味着A类最终继承自自己,对吧?我本以为这种循环继承会出问题,但我想不会!
  • “这意味着 A 类最终继承自自身,对吗?” – 不,不是那个意思,因为,正如你在前一句中所说,继承和实例是两个完全不同的东西。
【解决方案2】:

听起来令人费解,但实际上就是这样。 BasicObjectClassClassBasicObject

我认为用 ruby​​ 表达是不可能的,所以要让这项工作 MRI direcly creates internal structures for these few fundamental classes and wires them in this cyclical manner

void
Init_class_hierarchy(void)
{
    rb_cBasicObject = boot_defclass("BasicObject", 0);
    rb_cObject = boot_defclass("Object", rb_cBasicObject);
    rb_gc_register_mark_object(rb_cObject);

    /* resolve class name ASAP for order-independence */
    rb_set_class_path_string(rb_cObject, rb_cObject, rb_fstring_lit("Object"));

    rb_cModule = boot_defclass("Module", rb_cObject);
    rb_cClass =  boot_defclass("Class",  rb_cModule);

    rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
    RBASIC_SET_CLASS(rb_cClass, rb_cClass);
    RBASIC_SET_CLASS(rb_cModule, rb_cClass);
    RBASIC_SET_CLASS(rb_cObject, rb_cClass);
    RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
}

正如我们所见,没有两种类类型,一种是面向用户的,一种是“深度”类。这是同一个实体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 2013-02-20
    相关资源
    最近更新 更多