我对面向对象编程(OOP)比较陌生,但有一定的过程式编程背景。
目前我正在尝试通过GNU Smalltalk和Lovejoy的 "Smalltalk: Getting The Message"来理解OOP。
我对元类(metaclass)、Metaclass class以及超类(superclass)感到困惑。我可以看到超类 -> 类(class) -> 子类(subclass)的继承关系,但不明白元类在哪里如何适用。谢谢您的帮助...
我对面向对象编程(OOP)比较陌生,但有一定的过程式编程背景。
目前我正在尝试通过GNU Smalltalk和Lovejoy的 "Smalltalk: Getting The Message"来理解OOP。
我对元类(metaclass)、Metaclass class以及超类(superclass)感到困惑。我可以看到超类 -> 类(class) -> 子类(subclass)的继承关系,但不明白元类在哪里如何适用。谢谢您的帮助...
在免费在线书籍《Pharo by Example》的第10章(Pharo对象模型)中,有一个很好的描述。本章所解释的内容适用于所有Smalltalk实现。
类基面向对象有两种不同的关系:实例化和继承。
实例化是一个对象与它的类之间的关系,使用new
关键字等。通常情况下,它由任何对象的低级表示中的指针来实现。在Smalltalk中,anObject class
遍历这个指针;同时类也是对象,类的类被称为元类,但这与实例的关系相同。
继承是类之间的关系。你可以通过aClass superclass
从一个类到其超类,并一直这样做,直到你到达Object
类。在Smalltalk中,超类指针只是所有类定义的实例变量,superclass
消息是一个普通的访问器。
superclass
是一个对象的类的父类。即比当前对象的类高一级的类。
作为一个命名方法,它返回接收器的直接超类的名称。
例如,在 Squeak Smalltalk(及其衍生品 Pharo 和 Cuis)中,它被定义为
superclass
"Answer the receiver's superclass, a Class."
^superclass
在 Dolphin Smalltalk 中,它被定义为
`superclass
"Answer a which is the receiver's immediate
superclass (or if none)."
^superclass'
但是 - 类层次结构中的每个类实际上都是其父类的一个实例。因此,给定类的类是该类的元类。
例如,aSortedCollection是一个对象 - SortedCollection类的一个实例。
SortedCollection是一个类 - 在可浏览的类层次结构中命名为“SortedCollection”的类。同时,它也是元类的一个实例 - 一个匿名类,它具有单例对象实例,该实例是一个命名类。命名类在类层次结构中可见,但是元类(作为匿名类)则不太可见。这样做是为了Smalltalk
Smalltalk维护元类层次结构,即类的类的层次结构。它不太可见,因为它被保存为匿名系统对象,但是您可以在类浏览器中找到元类层次结构的顶级。Class Class和Class Metaclass都可以作为Class Behaviour的子子类找到,Class Behaviour本身是Class Object的子类。
人们说“在Smalltalk中,一切皆为对象”的原因之一是因为类Object
是所有其他类和对象的根源——它位于对象层次结构的最顶端,其中包含了类层次结构和元类层次结构。
(通常在这个阶段,我的大脑开始从耳朵流血,但以下三点有助于将其全部推回到我的头骨中)
如果您发送消息anInstanceOfAClass class
,您将得到返回的对象anInstanceOfAClass的类。
如果您发送消息anInstanceOfAClass class superclass
,您将得到返回的对象anInstanceOfAClass的类的父类。
如果您发送消息anInstanceOfAClass class class
,您将得到返回的对象anInstanceOfAClass的类的匿名单例元类。