为什么元类是元类的实例而不是类的实例?

发布于 2024-10-07 02:04:07 字数 40 浏览 7 评论 0原文

我想知道为什么使用两个不同的类,而不是只使用 Class 的原因。

I'd like to know the reasoning why there are two different classes used, instead of just using Class for both.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

大海や 2024-10-14 02:04:07

简短的答案是“您认为类是系统范围类的实例的假设是错误的,每个类实际上是类特定元类的实例”并且“它不会以任何其他方式工作”。

对答案的稍微修改是“这些名字真的很令人困惑,有时只记住他们的角色而不是试图太多地考虑他们是如何工作的”。

简短的回答:

元类是一个实例,就像所有其他普通的 Smalltalk 类一样,它需要它自己的专用类。常规 Smalltalk 对象的每个实例都有一个类,继承遵循类层次结构。每个类本身都是类特定元类的实例,继承遵循元类层次结构。每个元类本身就是 Metaclass 类的一个实例,虚拟机通过一个巧妙的小技巧将其短路,因为没有人发现为 Metaclass 类提供父类的用途,并且所有尝试过的人通常都会发现:在这个过程中,他们的理智开始受到侵蚀。

更长、仍然毛茸茸的答案:

Smalltalk 允许每个类包含特定于类的消息。这些大致相当于 Java 中的静态方法,但有一些显着的差异。这些区别之一是 Smalltalk 类实际上是实例化对象 - 它们是系统中的活动对象,具有从其他对象继承并包含实例变量的能力。

此属性导致系统中存在大量潜在的继承层次结构。每个常规对象都是一个类的实例,消息发送到搜索对象类的对象,然后跟踪类层次结构的继承链。发送到常规对象的消息按照类层次结构进行解析。

此外,类对象都是一个类特定元类的实例。发送到类对象的消息通过查找类特定元类来解析,然后在元类层次结构中向上查找。

再往上一层,每个元类对象都是系统范围内唯一的元类的实例。发送到元类对象的消息在系统范围内唯一的元类中查找,该元类不允许从任何人继承,并且在虚拟机中作为短路被硬连线。

从技术上讲,该系统有两个继承层次结构,第三个继承层次结构是通过短路伪造的。尽管有很多实际原因,但理论上没有理由在两点停止。这允许每个对象拥有它自己的、对象唯一的消息,每个类都拥有它自己的、类唯一的消息,并强制所有元类仅响应元类中定义的一组消息。

整洁吧?

The short answer is "Your assumption that Classes are instances of a system wide Class is wrong, each Class is actually an instance of a Class specific Metaclass" and also "it wouldn't work any other way".

A slight modification to the answer is "the names are really confusing, it's sometimes easier to just memorize their roles and not try to think too much about how they work".

Short hairy answer:

Metaclass is an instance, just like all other ordinary Smalltalk Classes, and it requires it's own dedicated class. Each instance of a regular Smalltalk object has a class, with inheritance following the class hierarchy. Each class is itself an instance of a class specific metaclass, with inheritance following the metaclass hierarchy. Each metaclass is itself an instance of the Metaclass class, which is short-circuited by the virtual machine in a neat little trick, since no one has found a use to giving the Metaclass class a parent, and all those who tried have generally found that their sanity was starting to erode in the process.

Longer, still hairy answer:

Smalltalk allows for each class to contain class specific messages. These are equivalent, roughly, to static methods in Java - but with some significant differences. One of these differences is that Smalltalk classes are actually instantiated objects - they are live objects in the system, complete with the ability to inherit from other objects, and to contain instance variables.

This property leads to a potential multitude of inheritance hierarchies in the system. Regular objects each are instances of exactly one Class, with message sends to an objects searching the objects' class, and then following up the inheritance chain of the Class hierarchy. Messages sent to regular objects are resolved up the Class hierarchy.

Also, class objects are each instances of one class specific Metaclass. Messages sent to a class object are resolved by lookups to the class specific metaclass, and then upwards on the metaclass hierarchy.

Up one more layer, metaclass objects each are instances of a system wide unique Metaclass class. Messages sent to a metaclass object are looked up in the system-wide unique Metaclass, which is not allowed to inherit from anybody and is hard-wired as a short circuit in the VM.

Technically, the system has two inheritance hierarchies, and a third one that is faked with a short circuit. There's no theoretical reason to stop at two, though there are lots of practical ones. This allows each object to have it's own, object unique, messages, each class to have it's own, class unique, messages, and forces all Metaclasses to answer to just one set of messages, defined in the Metaclass.

Neat, huh?

秋叶绚丽 2024-10-14 02:04:07

显然,一个类需要两个 ClassDescription:一个用于实例方法,另一个用于类方法。

现在,您可能仍然尝试对这两个对象使用 Class。我认为拥有元类的原因之一是你需要区分两者。如果您查看方法 theMetaClasstheNonMetaClass,您会发现它们相互镜像:通过此类成员从元类转到类,通过常规类指针(任何对象都拥有)。如果它们都是实例类,它们就无法知道它们实现的是哪一侧 - 除非有一个标志槽,这比创建子类更糟糕。

You clearly need two ClassDescriptions for a class: one for the instance methods, and one for the class methods.

Now, you might still try to use Class for both objects. I think one reason for having Metaclass is that you need to distinguish the two. If you look at the methods theMetaClass and theNonMetaClass, you see that they are mirroring each other: you go from metaclass to class throught thisclass member, and from class to metaclass through the regular class pointer (that any object posseses). If they both were of instance Class, they couldn't know which side they implement - unless there was a flag slot, which is worse than creating subclasses.

好听的两个字的网名 2024-10-14 02:04:07

这是我完全理解的事情之一...直到我必须解释它;-)经过多次提炼...

给定:

  • 对象的行为是由它的类指定的
  • 类是对象,太
  • 常规的对象/类有行为这仅对常规对象/类有意义

因此,类和实例应该具有不同的行为说明符(即类)。

从另一个角度来看,我们所说的“实例端”代表的实例端。我们所说的“类端”代表元类的实例端。

例如,Class 定义了 #addClassVarNamed: 和 #addInstVarNamed:,因为它们在实例端都有意义,而 Metaclass 只定义了 #addInstVarNamed:,因为没有类端类变量。

要深入了解细节,请参阅“Pharo 示例”或“Smalltalk 编程技术基础”

This is one of those things that I understand perfectly... until I have to explain it ;-) After much distillation...

Given:

  • an object's behavior is specified by its class
  • classes are objects, too
  • regular-objects/classes have behavior that only makes sense for regular-objects/classes

Therefore, classes and instances should have different behavior-specifiers (i.e. classes).

Looked at another way, what we call "instance side" represents the instance side of the class. What we call "class side" represents the instance side of the metaclass.

For example, Class defines #addClassVarNamed: and #addInstVarNamed:, because those both make sense on the instance side, where Metaclass only defines #addInstVarNamed:, because there are no class side class variables.

To dig deeper into the minutia, see "Pharo By Example" or "Fundamentals of Smalltalk Programming Technique"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文