元类

在面向对象程序设计中，元类（metaclass）是一种实例是类的类。普通的类定义的是特定对象的行为，元类定义的则是特定的类及其实例的行为。不是所有面向对象编程语言都支持元类。在它能做的事情之中，元类可以覆写任何给定方面类行为的程度是不同的。元类可以通过使类成为头等对象来实现，在这种情况下元类简单的就是构造类的一个对象。每个语言都有它自己的元对象协议，给出对象、类和元类如何交互的规则。
Smalltalk-80元类.
在Smalltalk中，所有东西都是对象。此外，Smalltalk是基于类的系统，这意味着所有对象都有一个类，它定义这个对象的结构（比如说这个类拥有实例变量），和这个对象所理解的消息。二者在一起蕴含了，在Smalltalk中，类是一个对象，因此类也需要是它的元类的实例。
元类在Smalltalk-80系统中的主要角色，是提供协议来初始化类变量，和建立元类的唯一实例（也就是其对应的类）的初始化实例。
实例联系.
为了允许类拥有它们自己的方法，和叫作类实例变量它们自己的，Smalltalk-80为每个类codice_1介入了它们自己的元类codice_2。就像实例方法实际上属于类一样，类方法实际上属于元类。在类中定义和，而在元类中定义类实例变量。
每个元类在效果上都是单例类。就像连体双胞胎，类和元类是共生的。元类有一个实例变量codice_3，它指向它结合的类。平常的Smalltalk，不将元类展示为单独的类，转而允许一起同时编辑类和它的元类。
要得到一个实例的类，需要向它发送消息调用codice_4方法。类和元类继承了其超类的codice_5方法，它返回接收者名字的字符串。例如，轿车对象codice_6是类codice_7的实例，则codice_8返回codice_7类对象，而codice_10返回codice_11；依次类推，codice_12返回codice_7的元类对象，而codice_14返回依赖于实现，有的是codice_15，即没有名字，有的是codice_16，即用空格分隔的类名字和codice_17。
在早期的Smalltalk-76中，创建新类的方式是向codice_18类发送codice_19消息。在Smalltalk-80中，codice_18是元类的基础类，它是类而不是元类。所有元类都是一个codice_21类的实例。codice_21类是codice_23的实例，而codice_23作为元类，也是codice_21类的实例。
继承联系.
在Smalltalk-80中，终端对象是一个整数、一个组件、或一台车等，而类是像codice_26、或codice_27或codice_7等这样的东西，除了codice_29之外，所有的类都有一个超类。元类所继承的元类，就是元类对应的类所继承的类的元类。
在一个消息被发送到对象的时候，方法的查找开始于它的类。如果没有找到则在上行超类链，停止于codice_29而不管找到与否。在一个消息被发送到一个类的时候，类方法查找开始于它的元类，并上行超类链至codice_31。直至codice_31，元类的超类层级并行于类的超类层级。在Smalltalk-80中，codice_31是codice_18的子类：
<syntaxhighlight lang="smalltalk">
Object class superclass == Class.
</syntaxhighlight>
类方法的查找在元类链之后仍可继续下去，所有元类都是codice_18的在继承层级中的子类，它是所有元类的抽象超类，它描述这些类的一般性质，继而最终可上溯至codice_29。
继承层级.
四个类提供描述新类的设施，下面是它们的继承层级（起自codice_29），和它们提供的主要设施：
方法查找次序.
下面是方法查找次序的辨析：
示意图.
下面是两个示意图，二者都是纵向连线表示实例联系，而横向连线表示继承联系。实例联系以codice_21（元类类）及其元类为顶端，而继承联系以codice_29（对象类）及其元类为中心，其中codice_31（对象元类）继承codice_18（类类）是串接元类继承链与类继承链的关键环节。前者图示采用Smalltalk-80蓝皮书的样式（但旋转了180°），将codice_21及其元类放置在最上方的独立两行，使得实例联系尽量成为树状向上汇聚；后者图示将codice_21及其元类放置在最左边，使得继承联系尽量都在同一行之上。
例子.
下列例子展示，从Smalltalk-80派生的Squeak和Pharo的样例代码的结构，它们的继承层级的根类实际上是codice_92，codice_92封装了所有对象都必须拥有的极小化的消息集合，它被设计为引发尽可能多的错误，用来支持代理（proxy）定义。例如Smalltalk-80的codice_29中，错误处理消息codice_95，和系统原始消息codice_96，就转而在codice_92中定义了。
在示意图中，纵向的绿色连接，展示继承联系的“子→父”关系（隐含的自下而上），横向的蓝色连接展示实例联系的“成员→容器”关系，从codice_98出的发蓝色连接，指向codice_98的最小实际容器，它是在调用在codice_98上的方法时查找方法的继承链起点：
这个结构由两个部份构成，用户部份有四个显式的对象和类及其两个隐式的元类：终端对象codice_101和codice_102，它们连接到的类codice_103和codice_104，它们两个连接到的右侧灰色节点表示的隐式的元类，其他的对象都是内建部份。
Objective-C元类.
在Objective-C中的元类，几乎同于Smalltalk-80的元类，这是因为Objective-C从Smalltalk引进了很多东西。就像Smalltalk，在Objective-C中实例变量和方法是对象的类定义的。类也是对象，因此它是元类的一个实例。
就像Smalltalk，在Objective-C中类方法，简单的是在类对象上调用的方法，因此一个类的类方法，必须定义为在它的元类中的实例方法。因为不同的类有不同的类方法集合，每个类都必须有它自己单独的元类。类和元类总是成对创建：运行时系统拥有函数codice_105和codice_106来分别的创建和注册类-元类对。
元类没有名字，但是到任何类对象的指针，可以通过泛化类型codice_18来提及（类似于用作到任何对象的指针的类型codice_108）。
元类都是相同的类即根类元类的实例，而根类元类是自身的实例。因为类方法是通过继承联系来继承的，就像Smalltalk，除了根类元类之外，元类继承联系必须并行于类继承联系（比如说如果类A的父类是类B，则A的元类的父类是B的元类）。
不同于Smalltalk，根类元类继承自根类自身（通常为使用Cocoa框架的codice_109）。这确保了所有的元类最终都是根类的子类，从而人们可以将根类的实例方法，它们通常是针对对象有用的实用方法，使用于类对象自身上。
Python元类.
在Python中，内建的类codice_110是元类。
类的定义，不包括它的实例对象的细节，如它们的字节为单位的大小，它们在内存中的二进制格局，它们是如何分配的，每次建立实例时自动调用的codice_111方法，诸如此类。不只是在建立新实例对象的时候，而且在每次访问实例对象的任何特性的时候，这些细节都起到作用。在没有元类的语言中，这些细节是在语言规定中定义的，并且不能被覆写（override）。
在Python中，元类codice_110控制着类行为的这些细节，默认定义出的类自身都是codice_110的实例。新的元类可以很容易定义为codice_110的子类从而覆写它，通过向类定义提供“关键字参数”codice_115就可以使用这个新的元类。
<syntaxhighlight lang="pycon">
Â»> type(b)
<class '__main__.B'>
Â»> print(type(B), B.__bases__, [*B.__dict__])
<class '__main__.M'> (<class '__main__.A'>,) ['__module__', '__doc__']
Â»> print(type(A), A.__bases__, [*A.__dict__])
<class '__main__.M'> (<class 'object'>,) ['__module__', '__dict__', '__weakref__', '__doc__']
Â»> print(type(M), M.__bases__, [*M.__dict__])
<class 'type'> (<class 'type'>,) ['__module__', '__doc__']
Â»> print(type(c), c.__bases__)
<class 'type'> (<class 'object'>,)
Â»> print(type(r), r.__bases__)
<class 'type'> ()
Â»> sorted({*r.__dict__} & {*c.__dict__})
['__delattr__', '__dir__', '__doc__', '__getattribute__', '__init__', '__new__', '__repr__', '__setattr__', '__sizeof__']
Â»> sorted({*r.__dict__} - {*c.__dict__})
['__class__', '__eq__', '__format__', '__ge__', '__gt__', '__hash__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__reduce__', '__reduce_ex__', '__str__', '__subclasshook__']
Â»> sorted({*c.__dict__} - {*r.__dict__})
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__dict__', '__dictoffset__', '__flags__', '__instancecheck__', '__itemsize__', '__module__', '__mro__', '__name__', '__prepare__', '__qualname__', '__subclasscheck__', '__subclasses__', '__text_signature__', '__weakrefoffset__', 'mro']
</syntaxhighlight>
例子.
考虑下面这个最简单的Python类：
<syntaxhighlight lang="python">
class Car:
</syntaxhighlight>
<syntaxhighlight lang="pycon">
Â»> new_car = Car(make='Toyota', model='Prius', year=2005, engine='Hybrid')
Â»> new_car(color='Green')
Â»> new_car.description
'Toyota Prius 2005 Hybrid Green'
</syntaxhighlight>
上面的例子包含了一些代码来处理初始化特性，也可以使用元类来完成这种任务：
<syntaxhighlight lang="python">
class AttributeInitType(type):
</syntaxhighlight>
这个元类只覆写实例类和对象创建部份功能。元类行为的所有其他方面仍由codice_110处理。现在可以重写类codice_7使用这个新元类：
<syntaxhighlight lang="python">
class Car(object, metaclass=AttributeInitType):
</syntaxhighlight>
Ruby元类.
Ruby通过介入其自称的特征类（eigenclass），提炼了Smalltalk-80的元类概念，去除了codice_21类，并重新定义了codice_119映射。变更可以图示如下：
特别要注意在Smalltalk的隐含的元类和Ruby类的特征类之间的对应。Ruby的特征类模型，使得隐式元类概念完全统一：所有对象codice_98，都有它自己的元对象，它叫作codice_98的特征类，它比codice_98高一个元层级。高阶特征类通常是纯粹概念上的存在，在大多数Ruby程序中，它们不包含任何方法也不存储任何（其他）数据。
下面的示意图展示Ruby样例代码的核心结构。这里的灰色节点表示打开codice_103和codice_102特征类后扩张出来的特征类。
图示还展示了Ruby中特征类的惰性求值。codice_102对象可以有它的特征类，作为向codice_102增加“单例方法”的结果而被求值（被分配）。
在语言和工具中的支持.
下面是支持元类的一些最显著的编程语言。
一些不甚广泛传播的语言支持元类，包括、OpenC++、OpenAda、、ObjVLisp、、MODEL-K、和MELDC。其中几种语言可追溯日期至1990年代早期并具有学术价值。
是Prolog的面向对象扩展，它也支持元类。
资源描述框架（RDF）和统一建模语言（UML）二者都支持元类。