Ich möchte die Gründe dafür wissen, warum zwei verschiedene Klassen verwendet werden, anstatt nur Klasse für beide zu verwenden.Warum sind Metaclasses Instanzen von Metaclass und nicht Class?
Antwort
Die kurze Antwort ist "Ihre Annahme, dass Klassen Instanzen einer systemweiten Klasse sind falsch, jede Klasse ist eigentlich eine Instanz einer Klasse spezifische Metaklasse" und auch "es würde nicht anders funktionieren".
Eine kleine Änderung an der Antwort ist: "Die Namen sind wirklich verwirrend, es ist manchmal einfacher, sich einfach ihre Rollen einzuprägen und nicht zu viel darüber nachzudenken, wie sie funktionieren."
Kurze behaarte Antwort:
Metaclass ist ein Beispiel, wie alle anderen normalen Smalltalk Klassen, und es erfordert eine eigene dedizierte Klasse ist. Jede Instanz eines regulären Smalltalk-Objekts hat eine Klasse, deren Vererbung der Klassenhierarchie folgt. Jede Klasse ist selbst eine Instanz einer klassenspezifischen Metaklasse, wobei die Vererbung der Metaklassenhierarchie folgt. Jede Metaklasse ist selbst eine Instanz der Klasse Metaclass, die von der virtuellen Maschine in einem kleinen Trick kurzgeschlossen wird, da niemand einen Nutzen daraus gezogen hat, der Klasse Metaclass ein Elternteil zu geben, und alle, die es versucht haben, haben das im Allgemeinen gefunden Ihre geistige Gesundheit begann dabei zu schwinden.
Längerer, noch behaarte Antwort:
Smalltalk ermöglicht es für jede Klasse klassenspezifische Nachrichten enthalten. Diese entsprechen in etwa den statischen Methoden in Java - allerdings mit einigen signifikanten Unterschieden. Einer dieser Unterschiede besteht darin, dass Smalltalk-Klassen tatsächlich instanziierte Objekte sind - sie sind Live-Objekte im System, komplett mit der Fähigkeit, von anderen Objekten zu übernehmen und Instanzvariablen zu enthalten.
Diese Eigenschaft führt zu einer möglichen Vielzahl von Vererbungshierarchien im System. Reguläre Objekte sind jeweils Instanzen genau einer Klasse, wobei die Nachricht an ein Objekt gesendet wird, das die Klasse der Objekte durchsucht, und dann die Vererbungskette der Klassenhierarchie verfolgt. Nachrichten, die an reguläre Objekte gesendet werden, werden in der Klassenhierarchie aufgelöst.
Auch Klassenobjekte sind jeweils Instanzen einer Klasse spezifischen Metaclass. Nachrichten, die an ein Klassenobjekt gesendet werden, werden durch Suchen in der klassenspezifischen Metaklasse und dann in der Metaklassenhierarchie aufgelöst.
Bis zu einer weiteren Ebene sind Metaclass-Objekte jeweils Instanzen einer systemweit eindeutigen Metaclass-Klasse. Nachrichten, die an ein Metaklassenobjekt gesendet werden, werden in der systemweit eindeutigen Metaklasse nachgeschlagen, die von niemandem erben darf und als Kurzschluss in der VM fest verdrahtet ist.
Technisch hat das System zwei Vererbungshierarchien und eine dritte, die mit einem Kurzschluss gefälscht ist. Es gibt keinen theoretischen Grund, um zwei zu stoppen, obwohl es viele praktische gibt.Dadurch kann jedes Objekt eigene, objektspezifische Nachrichten, Nachrichten, eigene Klassen, eindeutige Klassen und Nachrichten erhalten und alle Metaklassen gezwungen werden, auf nur eine Gruppe von Nachrichten zu antworten, die in der Metaklasse definiert sind.
Ordentlich, nicht wahr? Diese
Sie benötigen eindeutig zwei ClassDescriptions für eine Klasse: eine für die Instanzmethoden und eine für die Klassenmethoden.
Jetzt könnten Sie immer noch versuchen, Klasse für beide Objekte zu verwenden. Ich denke, ein Grund für Metaclass ist, dass Sie die beiden unterscheiden müssen. Wenn Sie die Methoden theMetaClass
und theNonMetaClass
betrachten, sehen Sie, dass sie sich gegenseitig spiegeln: Sie gehen von Metaklasse zu Klasse durch dieses Klassenmitglied und von Klasse zu Metaklasse durch den regulären Klassenzeiger (den jedes Objekt besitzt). Wenn sie beide der Instanz Klasse angehören, könnten sie nicht wissen, welche Seite sie implementieren - es sei denn, es gibt einen Flag-Slot, was schlimmer ist als das Erstellen von Unterklassen.
ist eines jener Dinge, die ich sehr gut verstehen ... bis ich es erklären müssen ;-) Nach viel Destillation ...
Gegeben:
- das Verhalten des Objekts angegeben durch seine Klasse
- Klassen-Objekte sind auch
- regular-Objekte/Klassen Verhalten haben, die Sinn macht nur für normale Objekte/Klassen
Daher sollten Klassen und Instanzen unterschiedliche Verhaltens-Spezifizierer (d. H. Klassen).
Anders ausgedrückt, was wir "Instanzseite" nennen, repräsentiert die Instanzseite der Klasse. Was wir "Klassenseite" nennen, repräsentiert die Instanzseite der Metaklasse.
Zum Beispiel definiert Class #addClassVarNamed: und #addInstVarNamed :, da beide auf der Instanzseite sinnvoll sind, wobei Metaclass nur #addInstVarNamed: definiert, da es keine klassenseitigen Klassenvariablen gibt.
tiefer in die Minutien zu graben „Pharo Beispiel vorangehen“ oder „Grundlagen der Smalltalk-Programmiertechnik“
Natürlich sehen, wenn Sie mit Klassen abschaffen zusammen, ala http://selflanguage.org/, Sie Machen Sie sich nie Sorgen um irgendetwas wie diese. – blueberryfields
Ja, aber warum sind Metaclasses Instanzen von Metaclass und nicht Klasse? –
Hoppla, meine Finger verglasen ... Es ist eine Namenskonvention. Die gleichen Wegpunkte sind Instanzen von Point. – blueberryfields