Common Lisp中标准对象和标准类的层次结构

10
我正在学习使用Lispworks学习Common Lisp,并尝试了解类系统。有一个称为standard-object的类,它被定义为:

standard-object类是standard-class的实例,是除了它本身以外的每个standard-class实例的超类。

(摘自http://www.lispworks.com/documentation/HyperSpec/Body/t_std_ob.htm#standard-object) 因此,它是standard-class的一个实例。
另一方面,standard-classstandard-object的一个子类。
>(subtypep 'standard-class 'standard-object)
=>T, T

标准对象如何既可以是标准类的超类,又可以是它的实例?如果我们将标准类定义为子类型,则应在其超类型(例如标准对象)定义之后定义它,那么超类如何成为实例呢?或者我的逻辑是错误的吗?
3个回答

12

enter image description here

CLOS是一个对象系统,其中CLOS概念本身是一级对象。类本身是实例 - 属于元类。涉及某些环状循环。

有一个实例standard-object。它是standard-class的一个实例。它本身也是一个类。所有标准的CLOS对象都将其作为超类。还有其他类型的对象,例如结构体。因此,standard-object作为所有典型CLOS对象的超类存在。

standard-class是它自己的一个实例。它是所有类对象的类。由于standard-object也是一个类,standard-object类的实例是standard-class类的一个实例。由于所有标准类也是CLOS对象,standard-class继承自standard-object

CL-USER 22 > (class-of (find-class 'standard-object))
#<STANDARD-CLASS STANDARD-CLASS 40F016A063>

standard-object类对象的类是standard-class

CL-USER 23 > (class-of (find-class 'standard-class))
#<STANDARD-CLASS STANDARD-CLASS 40F016A063>

standard-class类对象的类是standard-class

CL-USER 24 > (find-class 'standard-object)
#<STANDARD-CLASS STANDARD-OBJECT 40F017732B>

standard-object类本身既是一个对象又是一个类,它是所有CLOS对象的超类。

CL-USER 25 > (find-class 'standard-class)
#<STANDARD-CLASS STANDARD-CLASS 40F016A063>

standard-class类本身是一个对象和一个类。它是所有CLOS类的超类。


谢谢!看了这些例子,我现在好像明白了。 - TheEnt
2
从《元对象协议的艺术》附录D的第306页开始,展示了引导类CLOS语言的代码;包括如何解开所有循环依赖关系。我觉得这很有启发性,尽管我不能完全理解它。 - Clayton Stanley

2
为了理解这个概念,您需要了解“元类”的概念。元类的实例是一个类,而类的实例是一个对象,因此我们基本上有三层次结构。
“standard-class”是一个元类。“standard-object”是元类“standard-class”的实例,因此它是一个类。默认情况下,每个其他用户定义的类都继承自“standard-object”类。
因此,当您创建一个类时,您基本上是实例化“standard-class”元类,并且这个新类被“standard-object”类继承。

好的,我认为我理解了元类是什么,但我们是否同时定义standard-objectstandard-class?在我的脑海中,一切都是这样发生的: 0)我们定义类T; 1)我们定义类standard-object,它是T的子类型;没有standard-class! 2)我们将standard-class定义为standard-object的子类型,并使其成为元类 3)standard-object成为standard-class的实例 是这样吗?这对我来说有点奇怪。 - TheEnt
standard-class 不是 standard-object 的子类型。standard-object 是 standard-class 的一个实例。 - Ankur
那么为什么(subtypep 'standard-class 'standard-object)会返回true的答案呢? - TheEnt

1

我将尝试回答你似乎困惑的一个问题:

标准对象如何成为标准类的超类并同时成为其实例?

希望你熟悉数学中关系的概念。关系是在具有操作的集合上定义的。例如,“可被整除”,“是”,“等于”等都是关系。因此,“是实例”的关系和“是子类”的关系是不同的!子类必须是一个类,而实例可以是一个类,但通常是其他东西。如果你从自然界中举个例子:灵长类是哺乳动物的一个子类 - 这是“是子类”的关系。莱西(电影中的一只狗)是哺乳动物 - 这是“是实例”的关系的一个例子。

现在,可能让你困惑的是,某个东西的功能是作为另一个东西的实例来成为那个东西的类。这在自然界中确实不经常发生,但这里有一些我能想到的例子:

语言和语法。语法是一组定义语言的规则,语法本身也是一种语言(即它“是”语言的子类),而语言实例化语法规则,因此语言“是”语法的一个实例。


那个带有语法的例子绝对很棒,非常感谢,我现在完全明白了!我感觉定义中有一些错误,像是循环,但现在看起来没问题了。 - TheEnt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接