8

両方にClassを使用するのではなく、2つの異なるクラスが使用される理由を知りたいです。

4

3 に答える 3

5

簡単な答えは、「クラスがシステム全体のクラスのインスタンスであるというあなたの仮定は間違っています。各クラスは実際にはクラス固有のメタクラスのインスタンスです」そして「他の方法では機能しません」です。

答えのわずかな変更は、「名前は本当に紛らわしいです。役割を覚えるだけで、どのように機能するかについてあまり考えないほうが簡単な場合があります」です。

短い毛深い答え:

メタクラスは、他のすべての通常のSmalltalkクラスと同じようにインスタンスであり、独自の専用クラスが必要です。通常のSmalltalkオブジェクトの各インスタンスにはクラスがあり、継承はクラス階層に従います。各クラスはそれ自体がクラス固有のメタクラスのインスタンスであり、継承はメタクラス階層に従います。各メタクラスはそれ自体がメタクラスクラスのインスタンスであり、メタクラスクラスに親を与える方法を誰も見つけていないため、仮想マシンによって巧妙なトリックで短絡されます。彼らの正気はその過程で侵食され始めていました。

長く、まだ毛深い答え:

Smalltalkでは、各クラスにクラス固有のメッセージを含めることができます。これらは、大まかに言って、Javaの静的メソッドと同等ですが、いくつかの重要な違いがあります。これらの違いの1つは、Smalltalkクラスが実際にインスタンス化されたオブジェクトであるということです。これらはシステム内のライブオブジェクトであり、他のオブジェクトから継承し、インスタンス変数を含めることができます。

このプロパティは、システム内の潜在的な多数の継承階層につながります。通常のオブジェクトはそれぞれ、正確に1つのクラスのインスタンスであり、オブジェクトのクラスを検索し、クラス階層の継承チェーンをフォローアップするメッセージがオブジェクトに送信されます。通常のオブジェクトに送信されるメッセージは、クラス階層の上位で解決されます。

また、クラスオブジェクトは、1つのクラス固有のメタクラスの各インスタンスです。クラスオブジェクトに送信されたメッセージは、クラス固有のメタクラスへのルックアップによって解決され、次にメタクラス階層で上位になります。

もう1つのレイヤーでは、メタクラスオブジェクトはそれぞれ、システム全体で一意のメタクラスクラスのインスタンスです。メタクラスオブジェクトに送信されたメッセージは、システム全体で一意のメタクラスで検索されます。メタクラスは、誰からも継承することはできず、VMの短絡として配線されています。

技術的には、システムには2つの継承階層があり、3つ目は短絡で偽造されています。実用的な理由はたくさんありますが、2つで停止する理論的な理由はありません。これにより、各オブジェクトが独自のオブジェクト固有のメッセージを持ち、各クラスが独自のクラス固有のメッセージを持つことができ、すべてのメタクラスが、メタクラスで定義された1セットのメッセージにのみ応答するようになります。

きちんとね?

于 2010-12-10T22:38:23.140 に答える
3

クラスには明らかに2つのClassDescriptionsが必要です。1つはインスタンスメソッド用で、もう1つはクラスメソッド用です。

これで、両方のオブジェクトにClassを使用しようとする場合があります。Metaclassを使用する理由の1つは、2つを区別する必要があることだと思います。メソッドtheMetaClasstheNonMetaClassを見ると、それらが互いにミラーリングしていることがわかります。このクラスメンバーを介してメタクラスからクラスに移動し、通常のクラスポインタ(任意のオブジェクトが所有する)を介してクラスからメタクラスに移動します。両方がインスタンスクラスである場合、サブクラスを作成するよりも悪いフラグスロットがない限り、どちらの側を実装するかを知ることができませんでした。

于 2010-12-10T22:25:42.217 に答える
1

これは私が完全に理解していることの1つです...私がそれを説明しなければならないまで;-)多くの蒸留の後...

与えられた:

  • オブジェクトの動作はそのクラスによって指定されます
  • クラスもオブジェクトです
  • 通常のオブジェクト/クラスには、通常のオブジェクト/クラスに対してのみ意味のある動作があります

したがって、クラスとインスタンスは異なる動作指定子(つまりクラス)を持つ必要があります。

別の見方をすれば、「インスタンス側」と呼ばれるものは、クラスのインスタンス側を表します。「クラス側」と呼ばれるものは、メタクラスのインスタンス側を表します。

たとえば、Classは#addClassVarNamed:と#addInstVarNamed:を定義します。これは、どちらもインスタンス側で意味があるためです。Metaclassは#addInstVarNamed:のみを定義します。これは、クラス側のクラス変数がないためです。

細部を深く掘り下げるには、「PharoByExample」または「FundamentalsofSmalltalkProgrammingTechnique」を参照してください。

于 2010-12-11T00:46:45.050 に答える