Clase del 30/08/2007 (Diseño Avanzado con Objetos)

De Cuba-Wiki

Metaclasses

Una clase cuyas instancias son también clases es llamada “metaclase”.

En versiones anteriores de Smalltalk, existía solo una metaclase llamada Class. La dificultad de esto es que el protocolo de todas las clases estaba restringido a ser el mismo, ya que estaba especificado en un solo lugar.

Smalltalk-80 quita esta restricción, haciendo que cada clase sea instancia de su propia metaclase. Cuando una clase es creada, se crea automáticamente una nueva metaclase. Las metaclases son diferentes de las demás clases porque no son instancias de otras metaclases; son instancias de la clase llamada Metaclass. Además las metaclases no tienen nombres. Una metaclase puede ser accedida enviando a su instancia el mensaje unario class.

En Smalltalk-80, Class es una superclase abstracta de todas la metaclases. Class describe la naturaleza general de las clases. Cada metaclase agrega el comportamiento específico de su instancia. Cuando las metaclases se agregaron a Smalltalk-80, se hizo un gran cambio en la organización de clases. La jerarquía de subclases de las metaclases son una jerarquía paralela de la jerarquía de subclases de las clases que son sus instancias.

La clase abstracta llamada ClassDescription describe las clases y sus instancias. Class y Metaclass son subclases de ClassDescription. La superclase de la metaclase de Object es Class. Las metaclases heredan de Class su protocolo de creación de instancias.

Cuando una clase es creada, son creadas sus variables de clase con sus valores en nil. Las metaclase generalmente definen métodos que inicializan las variables de clase.

La variables de clase son accesibles desde se clase y su metaclase. La asignación de valores a las variables de clase puede hacerse en los métodos de clase, más que indirectamente vía mensajes privados en los métodos de instancia.


Protocol for Classes

Hay 4 clases (Behavior, ClassDescription, Metaclass y Class) que interactuan para proveer las facilidades necesarias para describir nuevas clases. La creación de nuevas clases involucra compilación de métodos y especificación de nombres para las variables de instancia, de clase, y la clase propiamente dicha. Cada clase es en definitiva una subclase de de la clase Object, expecto por Object que no tiene superclase. En particular, Class es subclase de ClassDescription, que es subclase de Behavior, que es subclase de Object. Cada objecto es instancia de una clase y cada clase es instancia de su metaclase. Una metaclase tiene una única instancia. Como las metaclases son objetos, también deben ser instancias de una clase. Cada metaclase es instancia de Metaclass. Metaclass es también una instancia de una metaclase. Este es un punto de circularidad en el sistema (la metaclase de Metaclass debe ser una instancia de Metaclass). Cada metaclase es una instancia de Metaclass. Los métodos de Class y sus superclases soportan el comportamiento común a los objetos que son clases. Los métodos de instancias de Metaclass agregan el comportamiento específico para clases particulares.

[ Ver Diagrama del Metamodelo de Smalltalk ]

Behavior

Behavior define el estado mínimo necesario para objetos que tienen instancias. En particular, define el estado usado por el intérprete. El estado descripto por Behavior incluye un enlace a la jerarquía de clases, un method dictionary, y una descripción de las instancias en términos del número y representación de sus variables. Provee protocolo para: • crear un method dictionary • crear instancias • crear una jerarquía de clases • acceder a los contenidos del method dictionary • acceder a las instancias y variables • acceder a la jerarquía de clases • enumerar subclases e instancias

Los métodos se almacenan en un diccionario que llamamos method dictionary. Las claves del mismo son los message selectors, los valores son la forma compilada de los métodos (instancias de CompiledMethod). Los mensajes que acceden el contenido del method dictionary distinguen entre los selectores en el method dictionary local de la clase, y aquellos en los de la clase y cada una de sus superclases. Una instancia puede tener variables de instancia nombradas, variables de isntancia indexadas y variables de clase. De nuevo, la distinción entre variables especificadas localmente y variables heredadas se hace en el protocolo de acceso. El protocolo de acceso incluye mensajes para obtener colecciones de superclases y subclases de una clase. Estos mensajes distinguen entre la superclase y subclases inmediatas de una clase, y todas las clases en la cadena de superclases. El protocolo de testing provee mensajes para encontrar información sobre la estructura de una clase y la forma de sus instancias. La estructura de una clase consiste de su relación con otras clases, su capacidad de responder mensajes, la clase en que está especificado un mensaje, etc. Se puede también testear el contenido del method dictionary para encontrar que clase (si la hay) implementa un selector particular, cuando una clase puede responder a un mensaje, y que métodos referencias a variables o literales. Las clases que tienen variables de instancia indexadas se llaman de tamaño variable y las que no de tamaño fijo. Las variables de todas las clases de tamaño fijo se almacenan como punteros. Las de tamaño variable pueden contener punteros, bytes o words. Los mensajes especificados en Behavior también soportan listar objetos asociados a una clase y aplicarlos como argumentos de un bloque. Behavior no provee una representación para nombres de variables de instancia y clase, ni para un nombre y comentario de una clase. Las representaciones para nombres de variables de instancia y nombre y comentario de una clase son provistas en ClassDescription, una subclase de Behavior. ClassDescription tiene dos subclases: Class y Metaclass. Class describe la representación de nombres de variables de clase y pool variables. Una metaclase comparte las variables de clase y pool con su única instancia. Class agrega protocolo para agregar y eliminar variables de clase y pool, y crear varios tipos de subclases. Metaclass agrega un mensaje de inicialización para crear una subclase de si misma, es decir para crear una metaclase de una nueva clase.

ClassDescription

Representa el nombramiento de clases y variables de instancia, y comentario de clases. Se provee como superclase común para Class y Metaclass. Específicamente agrega estructura para organizar los pares selectors/método del method dictionary. Esta organización es un esquema de categorización simple donde se agrupan y nombran subconjuntos del method dictionary. El esquema de caregorización tiene impacto en el protocolo para compilar ya que un compiled method debe colocarse en una cierta categoría.

Metaclass

El rol primario de una metaclase es proveer protocolo para inicializar variables de clase y para crear instancias inicializadas de su única instancia. Por lo tanto los mensajes clave agregados por Metaclass son mensajes de inicialización (uno se envia a Metaclass para crear una subclase de ella, y otro se envía a una instancia de Metaclass para crear su única instancia).

Class

Las instancias de Class describen la representación y comportamiento de los objetos. En particular, Class agrega la representación para nombres de variables de clase y pools compartidos (shared pools).