メタクラス
オブジェクト指向プログラミングにおいてメタクラスとは、インスタンスがクラスとなるクラスのことである。通常のクラスがそのインスタンスの振る舞いを定義するように、メタクラスはそのインスタンスであるクラスを、そして更にそのクラスのインスタンスの振る舞いを定義する。全てのオブジェクト指向プログラミング言語でメタクラスが利用できるわけではない。利用できるものの中でもクラスの振る舞いが定義できる範囲は様々である。各言語はそれぞれ独自のメタオブジェクトプロトコル(MOP)を備えている。メタオブジェクトプロトコルとは、クラスそのものの挙動をもオブジェクト指向のルールで記述し、初期化やインスタンス化のルール、実行状態の管理などをカスタマイズする機構である。Smalltalk、CLOSが代表的である。
Pythonの組み込み(ビルトイン)クラス codice_1 はメタクラスである。次に示す単純なPythonのクラスについて説明する。
このコードを実行した時、codice_2 は codice_1 のインスタンスになっている。上記の codice_2 クラスのソースコードには codice_5 メソッドが codice_2 のインスタンスが生成されるたびに呼ばれるといった細々としたことは記述されていない。メタクラスが用意されていない言語ではこのような振る舞いは言語仕様で定義されており、変更することは不可能である。Pythonではメタクラス codice_1 がこれらの動作を決定しており、codice_1 の代わりに違うメタクラスを使用することでこれらの振る舞いを変更することが可能である。
上に示した例は4つの属性 codice_9 と codice_10、codice_11、codice_12 の辺りが冗長である。メタクラスを使えば、この冗長さを取り除くことが可能である。Pythonではメタクラスは codice_1 のサブクラスとして定義するのが最も簡単である。
このメタクラスはインスタンスの生成を上書きしているだけで、他の機能はまだ codice_1 が処理している。
さて、このメタクラスを用いて codice_2 クラスを書き直すことが可能である。Python 2ではクラス定義中で codice_16 にこのメタクラスを代入すればよい(Python 3では代わりに codice_17 と名前付き引数として与える)。
これで、codice_2 のインスタンスを次のように生成できる。
Smalltalkでは全てがオブジェクトである。また、Smalltalkはクラスベースであるため、オブジェクトは必ず、そのオブジェクトの構造（端的にはそのオブジェクトが有するインスタンス変数）や、そのオブジェクトがどんなメッセージを理解するのか（端的にはコールできるメソッド）を定義したいずれかのクラスに属さなければならない。このルールにおいてクラスも例外ではなく、Smalltalkではクラスもオブジェクトであり、同時に別のクラスのインスタンスでもある。このクラスのクラス、つまりあるクラスが属する特殊なクラスが「メタクラス」である。
例えば、「自動車」クラスcodice_2から生成されたオブジェクトcodice_20が、codice_2のインスタンスであり、codice_2というクラスに属しているのと同じように、クラスcodice_2自身にも自らが属しているクラス、つまりメタクラスが存在する。原則としてSmalltalkでメタクラスは無名扱いだが、便宜的にクラス名にcodice_24を付して呼称する慣習がある。codice_2なら、そのメタクラスはcodice_26である。なおこの表記は（クラスに限らず）あるオブジェクトが属するクラスを第一級オブジェクトとして得るためのSmalltalk式としての意味も併せ持つ（codice_27）。
クラスメソッド（クラスがコールできるメソッド）は、通常、メタクラスに定義されている。これはインスタンスメソッドがクラスに定義されているのと考え方は同じである。
インスタンスメソッドの場合、たとえば整数の「2」というオブジェクトに何らかのメッセージを送ると、2が属するcodice_28というクラスから対応するメソッドがないか探し始める。codice_28に見つからなければそのスーパークラスであるcodice_30で…というようにスーパークラスを次々と手繰ってゆき、最後のcodice_31というルートクラスまで探索を続ける。
クラスメソッドの場合も考え方はほとんど変わらない。たとえばcodice_28というクラスに対してメッセージを送ると、メソッド検索はそのクラスであるcodice_33から開始される。そしてインスタンスメソッドの場合と同様に、codice_33のスーパークラスであるcodice_35、さらにそのスーパークラスを次々と手繰り、codice_36（codice_31クラスのメタクラス）まで探索を続ける。なおSmalltalkにおいては、メタクラスの継承関係は原則としてそのインスタンスであるクラスの継承関係と一致する。つまりcodice_28のスーパークラスがcodice_30なら、そのメタクラス同士も同じ関係、すなわち、codice_33のスーパークラスはcodice_35である。ただしcodice_36だけは例外で、Objectのスーパークラスが未定義（nil）であるのに対し、codice_36のスーパークラスはcodice_44と定められている。したがって、クラスへのメッセージ送信に伴うメソッド探索はcodice_36では終了せず、クラスとしての振る舞いを定めたcodice_44とそのスーパークラスパスにある二つのクラス（codice_47とcodice_48。後述）を経てcodice_31に行き着くまで続行される。同時にこのことはSmalltalkにおいてクラスもオブジェクトである、すなわちクラスcodice_31の（サブ）インスタンスであり、通常のクラスのインスタンス同様codice_31に定義されたメソッドをコールできることの理由をうまく説明している。
初期のSmalltalk（Smalltalk-76）には、同じくcodice_44と名付けられたたったひとつのメタクラスしか用意されていなかった。つまりこのことは、すべてのクラスはcodice_44のインスタンスであり、他のクラスと同じ共通のメソッドしか持つことができなかった（たとえば、新しいインスタンスを作るためのcodice_54というメソッドなど）ということを意味する。その後、クラスが独自のメソッド（クラスメソッド）やインスタンス変数（クラスインスタンス変数と呼ばれる。クラスとそのインスタンスで共有できるクラス変数と混同されやすいが別物である）を持てるように、Smalltalk-80では改めてクラスそれぞれが固有のメタクラスが生成されるように拡張され今のかたちになった。
クラスのクラスであるメタクラスは、インスタンスのクラスである通常のクラスほどには独自性を要求されないので、すべてのメタクラスはcodice_55という名のひとつクラスのインスタンスとして位置づけられている。ちなみにcodice_55のメタクラスはcodice_57だが、同時にこれは前述のルールに則りcodice_55のインスタンスでもある。このトリックによって、さらにメタ、さらにそのメタ…と永遠に繰り返さずにも済むようになっている。
メタクラスはクラス生成時に同時に生成される。より具体的には、あるクラス（将来のスーパークラス）に対して、そのサブクラスとして例えばcodice_59を生成するように命ずると、まず暗黙のうちにcodice_60が生成され、そのインスタンスとしてcodice_59が生成される。先にも述べたがメタクラスは無名であり、クラスブラウザのクラス一覧にも現れえない。しかし、メタクラスが必ずクラスとペアで生成されることを利用して、クラスブラウザではclassボタン（古典的なクラスブラウザではクラス一覧を表示する枠に設置されている）を押して表示を切り替えることで対応するメタクラスの定義にアクセスしたりその内容（クラスインスタンス変数やクラスメソッド）を編集可能になっている。
クラスおよびメタクラスの振る舞いは次の4段階の継承階層を経て定義されている。
Rubyでは、クラス自体がClassというクラスのインスタンスであり、codice_62という形でクラスを動的に生成することもできる。
ClassはModuleを継承しており、動的なメソッドの操作といったクラスに共通な機能があるほか、特異メソッド（あるオブジェクトだけに有効なメソッド）を使うことで、Smalltalk-76のような単一のメタクラスでクラスごとの多様性をもたせることができる。
具体的には、存在しないメソッドの呼び出しや、継承・メソッドの追加といったタイミングで呼び出されるフック関数を特異メソッドとして実装することができる。
有名なプログラミング言語でメタクラスが利用可能なものは以下である。
次のようにそれほど普及していない言語の中にはメタクラスが利用できるものもある。いくつかは研究目的であり、1990年代初頭にまで遡る: OpenJavaやOpenC++、OpenAda、CorbaScript、ObjVLisp、Object-Z、MODEL-K、XOTcl、MELDCなど。
また、Prologのオブジェクト指向拡張であるLogtalkでもメタクラスが利用できる。
さらに、Resource Description Framework (RDF)とUnified Modeling Language (UML)は両者共にメタクラスが利用できる。